
// Generated from Jass.g4 by ANTLR 4.13.2


#include "JassListener.h"
#include "JassVisitor.h"

#include "JassParser.h"


using namespace antlrcpp;
using namespace antlrcppjassparser;

using namespace antlr4;

namespace {

struct JassParserStaticData final {
  JassParserStaticData(std::vector<std::string> ruleNames,
                        std::vector<std::string> literalNames,
                        std::vector<std::string> symbolicNames)
      : ruleNames(std::move(ruleNames)), literalNames(std::move(literalNames)),
        symbolicNames(std::move(symbolicNames)),
        vocabulary(this->literalNames, this->symbolicNames) {}

  JassParserStaticData(const JassParserStaticData&) = delete;
  JassParserStaticData(JassParserStaticData&&) = delete;
  JassParserStaticData& operator=(const JassParserStaticData&) = delete;
  JassParserStaticData& operator=(JassParserStaticData&&) = delete;

  std::vector<antlr4::dfa::DFA> decisionToDFA;
  antlr4::atn::PredictionContextCache sharedContextCache;
  const std::vector<std::string> ruleNames;
  const std::vector<std::string> literalNames;
  const std::vector<std::string> symbolicNames;
  const antlr4::dfa::Vocabulary vocabulary;
  antlr4::atn::SerializedATNView serializedATN;
  std::unique_ptr<antlr4::atn::ATN> atn;
};

::antlr4::internal::OnceFlag jassParserOnceFlag;
#if ANTLR4_USE_THREAD_LOCAL_CACHE
static thread_local
#endif
std::unique_ptr<JassParserStaticData> jassParserStaticData = nullptr;

void jassParserInitialize() {
#if ANTLR4_USE_THREAD_LOCAL_CACHE
  if (jassParserStaticData != nullptr) {
    return;
  }
#else
  assert(jassParserStaticData == nullptr);
#endif
  auto staticData = std::make_unique<JassParserStaticData>(
    std::vector<std::string>{
      "program", "typeDeclaration", "type", "global", "local", "assignTail", 
      "multDivExpression", "simpleArithmeticExpression", "boolComparisonExpression", 
      "boolEqualityExpression", "boolAndsExpression", "boolExpression", 
      "baseExpression", "expression", "functionExpression", "argsList", 
      "statement", "ifStatementPartial", "param", "paramList", "globalsBlock", 
      "typeDeclarationBlock", "nativeBlock", "block", "functionBlock", "statements", 
      "newlines", "newlines_opt", "pnewlines"
    },
    std::vector<std::string>{
      "", "'*'", "'/'", "'+'", "'-'", "'<'", "'>'", "'<='", "'>='", "'=='", 
      "'!='", "'['", "']'", "'('", "')'", "','", "'='", "'globals'", "'endglobals'", 
      "'native'", "'function'", "'takes'", "'returns'", "'endfunction'", 
      "'nothing'", "'call'", "'set'", "'return'", "'array'", "'type'", "'extends'", 
      "'if'", "'then'", "'else'", "'endif'", "'elseif'", "'constant'", "'local'", 
      "'loop'", "'endloop'", "'exitwhen'", "'debug'", "", "", "", "", "", 
      "", "'null'", "'true'", "'false'", "'not'", "'or'", "'and'"
    },
    std::vector<std::string>{
      "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "EQUALS", 
      "GLOBALS", "ENDGLOBALS", "NATIVE", "FUNCTION", "TAKES", "RETURNS", 
      "ENDFUNCTION", "NOTHING", "CALL", "SET", "RETURN", "ARRAY", "TYPE", 
      "EXTENDS", "IF", "THEN", "ELSE", "ENDIF", "ELSEIF", "CONSTANT", "LOCAL", 
      "LOOP", "ENDLOOP", "EXITWHEN", "DEBUG", "STRING_LITERAL", "INTEGER", 
      "HEX_CONSTANT", "DOLLAR_HEX_CONSTANT", "RAWCODE", "REAL", "NULL", 
      "TRUE", "FALSE", "NOT", "OR", "AND", "ID", "WS", "NEWLINE"
    }
  );
  static const int32_t serializedATNSegment[] = {
  	4,1,56,398,2,0,7,0,2,1,7,1,2,2,7,2,2,3,7,3,2,4,7,4,2,5,7,5,2,6,7,6,2,
  	7,7,7,2,8,7,8,2,9,7,9,2,10,7,10,2,11,7,11,2,12,7,12,2,13,7,13,2,14,7,
  	14,2,15,7,15,2,16,7,16,2,17,7,17,2,18,7,18,2,19,7,19,2,20,7,20,2,21,7,
  	21,2,22,7,22,2,23,7,23,2,24,7,24,2,25,7,25,2,26,7,26,2,27,7,27,2,28,7,
  	28,1,0,1,0,1,0,1,0,5,0,63,8,0,10,0,12,0,66,9,0,1,0,5,0,69,8,0,10,0,12,
  	0,72,9,0,3,0,74,8,0,1,1,1,1,1,1,1,1,1,1,1,1,1,2,1,2,1,2,1,2,3,2,86,8,
  	2,1,3,3,3,89,8,3,1,3,1,3,1,3,1,3,1,3,3,3,96,8,3,1,3,1,3,1,3,1,3,1,3,3,
  	3,103,8,3,1,4,1,4,1,4,1,4,1,4,1,4,1,4,1,4,1,4,1,4,1,4,3,4,116,8,4,1,5,
  	1,5,1,5,1,6,1,6,1,6,1,6,1,6,1,6,1,6,1,6,1,6,5,6,130,8,6,10,6,12,6,133,
  	9,6,1,7,1,7,1,7,1,7,1,7,1,7,1,7,1,7,1,7,5,7,144,8,7,10,7,12,7,147,9,7,
  	1,8,1,8,1,8,1,8,1,8,1,8,1,8,1,8,1,8,1,8,1,8,1,8,1,8,1,8,1,8,5,8,164,8,
  	8,10,8,12,8,167,9,8,1,9,1,9,1,9,1,9,1,9,1,9,1,9,1,9,1,9,5,9,178,8,9,10,
  	9,12,9,181,9,9,1,10,1,10,1,10,1,10,1,10,1,10,5,10,189,8,10,10,10,12,10,
  	192,9,10,1,11,1,11,1,11,1,11,1,11,1,11,5,11,200,8,11,10,11,12,11,203,
  	9,11,1,12,1,12,1,12,1,12,1,12,1,12,1,12,1,12,1,12,1,12,1,12,1,12,1,12,
  	1,12,1,12,1,12,1,12,1,12,1,12,1,12,1,12,1,12,1,12,1,12,1,12,1,12,3,12,
  	231,8,12,1,13,1,13,1,14,1,14,1,14,1,14,1,14,1,14,1,14,1,14,3,14,243,8,
  	14,1,15,1,15,1,15,1,15,1,15,1,15,3,15,251,8,15,1,16,1,16,1,16,1,16,1,
  	16,1,16,1,16,1,16,1,16,1,16,1,16,1,16,1,16,1,16,1,16,1,16,1,16,1,16,1,
  	16,1,16,1,16,1,16,1,16,1,16,1,16,1,16,1,16,1,16,1,16,1,16,1,16,1,16,1,
  	16,1,16,1,16,1,16,1,16,1,16,1,16,1,16,3,16,293,8,16,1,17,1,17,1,17,1,
  	17,1,17,1,17,1,17,1,17,1,17,1,17,1,17,1,17,1,17,1,17,1,17,1,17,1,17,1,
  	17,1,17,1,17,1,17,1,17,1,17,1,17,3,17,319,8,17,1,18,1,18,1,18,1,19,1,
  	19,1,19,1,19,1,19,1,19,3,19,330,8,19,1,20,1,20,1,20,5,20,335,8,20,10,
  	20,12,20,338,9,20,1,20,1,20,1,20,1,21,5,21,344,8,21,10,21,12,21,347,9,
  	21,1,22,3,22,350,8,22,1,22,1,22,1,22,1,22,1,22,1,22,1,22,1,22,1,23,1,
  	23,3,23,362,8,23,1,24,3,24,365,8,24,1,24,1,24,1,24,1,24,1,24,1,24,1,24,
  	1,24,1,24,1,24,1,24,1,25,5,25,379,8,25,10,25,12,25,382,9,25,1,26,1,26,
  	3,26,386,8,26,1,27,1,27,1,27,3,27,391,8,27,1,28,1,28,1,28,3,28,396,8,
  	28,1,28,0,6,12,14,16,18,20,22,29,0,2,4,6,8,10,12,14,16,18,20,22,24,26,
  	28,30,32,34,36,38,40,42,44,46,48,50,52,54,56,0,0,430,0,73,1,0,0,0,2,75,
  	1,0,0,0,4,85,1,0,0,0,6,102,1,0,0,0,8,115,1,0,0,0,10,117,1,0,0,0,12,120,
  	1,0,0,0,14,134,1,0,0,0,16,148,1,0,0,0,18,168,1,0,0,0,20,182,1,0,0,0,22,
  	193,1,0,0,0,24,230,1,0,0,0,26,232,1,0,0,0,28,242,1,0,0,0,30,250,1,0,0,
  	0,32,292,1,0,0,0,34,318,1,0,0,0,36,320,1,0,0,0,38,329,1,0,0,0,40,331,
  	1,0,0,0,42,345,1,0,0,0,44,349,1,0,0,0,46,361,1,0,0,0,48,364,1,0,0,0,50,
  	380,1,0,0,0,52,385,1,0,0,0,54,390,1,0,0,0,56,395,1,0,0,0,58,74,3,52,26,
  	0,59,60,3,54,27,0,60,64,3,42,21,0,61,63,3,46,23,0,62,61,1,0,0,0,63,66,
  	1,0,0,0,64,62,1,0,0,0,64,65,1,0,0,0,65,70,1,0,0,0,66,64,1,0,0,0,67,69,
  	3,48,24,0,68,67,1,0,0,0,69,72,1,0,0,0,70,68,1,0,0,0,70,71,1,0,0,0,71,
  	74,1,0,0,0,72,70,1,0,0,0,73,58,1,0,0,0,73,59,1,0,0,0,74,1,1,0,0,0,75,
  	76,5,29,0,0,76,77,5,54,0,0,77,78,5,30,0,0,78,79,5,54,0,0,79,80,3,52,26,
  	0,80,3,1,0,0,0,81,86,5,54,0,0,82,83,5,54,0,0,83,86,5,28,0,0,84,86,5,24,
  	0,0,85,81,1,0,0,0,85,82,1,0,0,0,85,84,1,0,0,0,86,5,1,0,0,0,87,89,5,36,
  	0,0,88,87,1,0,0,0,88,89,1,0,0,0,89,90,1,0,0,0,90,91,3,4,2,0,91,92,5,54,
  	0,0,92,93,3,52,26,0,93,103,1,0,0,0,94,96,5,36,0,0,95,94,1,0,0,0,95,96,
  	1,0,0,0,96,97,1,0,0,0,97,98,3,4,2,0,98,99,5,54,0,0,99,100,3,10,5,0,100,
  	101,3,52,26,0,101,103,1,0,0,0,102,88,1,0,0,0,102,95,1,0,0,0,103,7,1,0,
  	0,0,104,105,5,37,0,0,105,106,3,4,2,0,106,107,5,54,0,0,107,108,3,52,26,
  	0,108,116,1,0,0,0,109,110,5,37,0,0,110,111,3,4,2,0,111,112,5,54,0,0,112,
  	113,3,10,5,0,113,114,3,52,26,0,114,116,1,0,0,0,115,104,1,0,0,0,115,109,
  	1,0,0,0,116,9,1,0,0,0,117,118,5,16,0,0,118,119,3,26,13,0,119,11,1,0,0,
  	0,120,121,6,6,-1,0,121,122,3,24,12,0,122,131,1,0,0,0,123,124,10,3,0,0,
  	124,125,5,1,0,0,125,130,3,24,12,0,126,127,10,2,0,0,127,128,5,2,0,0,128,
  	130,3,24,12,0,129,123,1,0,0,0,129,126,1,0,0,0,130,133,1,0,0,0,131,129,
  	1,0,0,0,131,132,1,0,0,0,132,13,1,0,0,0,133,131,1,0,0,0,134,135,6,7,-1,
  	0,135,136,3,12,6,0,136,145,1,0,0,0,137,138,10,3,0,0,138,139,5,3,0,0,139,
  	144,3,12,6,0,140,141,10,2,0,0,141,142,5,4,0,0,142,144,3,12,6,0,143,137,
  	1,0,0,0,143,140,1,0,0,0,144,147,1,0,0,0,145,143,1,0,0,0,145,146,1,0,0,
  	0,146,15,1,0,0,0,147,145,1,0,0,0,148,149,6,8,-1,0,149,150,3,14,7,0,150,
  	165,1,0,0,0,151,152,10,5,0,0,152,153,5,5,0,0,153,164,3,14,7,0,154,155,
  	10,4,0,0,155,156,5,6,0,0,156,164,3,14,7,0,157,158,10,3,0,0,158,159,5,
  	7,0,0,159,164,3,14,7,0,160,161,10,2,0,0,161,162,5,8,0,0,162,164,3,14,
  	7,0,163,151,1,0,0,0,163,154,1,0,0,0,163,157,1,0,0,0,163,160,1,0,0,0,164,
  	167,1,0,0,0,165,163,1,0,0,0,165,166,1,0,0,0,166,17,1,0,0,0,167,165,1,
  	0,0,0,168,169,6,9,-1,0,169,170,3,16,8,0,170,179,1,0,0,0,171,172,10,3,
  	0,0,172,173,5,9,0,0,173,178,3,16,8,0,174,175,10,2,0,0,175,176,5,10,0,
  	0,176,178,3,16,8,0,177,171,1,0,0,0,177,174,1,0,0,0,178,181,1,0,0,0,179,
  	177,1,0,0,0,179,180,1,0,0,0,180,19,1,0,0,0,181,179,1,0,0,0,182,183,6,
  	10,-1,0,183,184,3,18,9,0,184,190,1,0,0,0,185,186,10,2,0,0,186,187,5,53,
  	0,0,187,189,3,18,9,0,188,185,1,0,0,0,189,192,1,0,0,0,190,188,1,0,0,0,
  	190,191,1,0,0,0,191,21,1,0,0,0,192,190,1,0,0,0,193,194,6,11,-1,0,194,
  	195,3,20,10,0,195,201,1,0,0,0,196,197,10,2,0,0,197,198,5,52,0,0,198,200,
  	3,20,10,0,199,196,1,0,0,0,200,203,1,0,0,0,201,199,1,0,0,0,201,202,1,0,
  	0,0,202,23,1,0,0,0,203,201,1,0,0,0,204,231,5,54,0,0,205,231,5,42,0,0,
  	206,231,5,43,0,0,207,231,5,44,0,0,208,231,5,45,0,0,209,231,5,46,0,0,210,
  	231,5,47,0,0,211,212,5,20,0,0,212,231,5,54,0,0,213,231,5,48,0,0,214,231,
  	5,49,0,0,215,231,5,50,0,0,216,217,5,54,0,0,217,218,5,11,0,0,218,219,3,
  	26,13,0,219,220,5,12,0,0,220,231,1,0,0,0,221,231,3,28,14,0,222,223,5,
  	13,0,0,223,224,3,26,13,0,224,225,5,14,0,0,225,231,1,0,0,0,226,227,5,51,
  	0,0,227,231,3,24,12,0,228,229,5,4,0,0,229,231,3,24,12,0,230,204,1,0,0,
  	0,230,205,1,0,0,0,230,206,1,0,0,0,230,207,1,0,0,0,230,208,1,0,0,0,230,
  	209,1,0,0,0,230,210,1,0,0,0,230,211,1,0,0,0,230,213,1,0,0,0,230,214,1,
  	0,0,0,230,215,1,0,0,0,230,216,1,0,0,0,230,221,1,0,0,0,230,222,1,0,0,0,
  	230,226,1,0,0,0,230,228,1,0,0,0,231,25,1,0,0,0,232,233,3,22,11,0,233,
  	27,1,0,0,0,234,235,5,54,0,0,235,236,5,13,0,0,236,237,3,30,15,0,237,238,
  	5,14,0,0,238,243,1,0,0,0,239,240,5,54,0,0,240,241,5,13,0,0,241,243,5,
  	14,0,0,242,234,1,0,0,0,242,239,1,0,0,0,243,29,1,0,0,0,244,251,3,26,13,
  	0,245,246,3,26,13,0,246,247,5,15,0,0,247,248,3,30,15,0,248,251,1,0,0,
  	0,249,251,1,0,0,0,250,244,1,0,0,0,250,245,1,0,0,0,250,249,1,0,0,0,251,
  	31,1,0,0,0,252,253,5,25,0,0,253,254,3,28,14,0,254,255,3,52,26,0,255,293,
  	1,0,0,0,256,257,5,26,0,0,257,258,5,54,0,0,258,259,5,16,0,0,259,260,3,
  	26,13,0,260,261,3,52,26,0,261,293,1,0,0,0,262,263,5,26,0,0,263,264,5,
  	54,0,0,264,265,5,11,0,0,265,266,3,26,13,0,266,267,5,12,0,0,267,268,5,
  	16,0,0,268,269,3,26,13,0,269,270,3,52,26,0,270,293,1,0,0,0,271,272,5,
  	27,0,0,272,273,3,26,13,0,273,274,3,52,26,0,274,293,1,0,0,0,275,276,5,
  	27,0,0,276,293,3,52,26,0,277,278,5,40,0,0,278,279,3,26,13,0,279,280,3,
  	52,26,0,280,293,1,0,0,0,281,293,3,8,4,0,282,283,5,38,0,0,283,284,3,52,
  	26,0,284,285,3,50,25,0,285,286,5,39,0,0,286,287,3,52,26,0,287,293,1,0,
  	0,0,288,289,5,31,0,0,289,293,3,34,17,0,290,291,5,41,0,0,291,293,3,32,
  	16,0,292,252,1,0,0,0,292,256,1,0,0,0,292,262,1,0,0,0,292,271,1,0,0,0,
  	292,275,1,0,0,0,292,277,1,0,0,0,292,281,1,0,0,0,292,282,1,0,0,0,292,288,
  	1,0,0,0,292,290,1,0,0,0,293,33,1,0,0,0,294,295,3,26,13,0,295,296,5,32,
  	0,0,296,297,3,52,26,0,297,298,3,50,25,0,298,299,5,34,0,0,299,300,3,52,
  	26,0,300,319,1,0,0,0,301,302,3,26,13,0,302,303,5,32,0,0,303,304,3,52,
  	26,0,304,305,3,50,25,0,305,306,5,33,0,0,306,307,3,52,26,0,307,308,3,50,
  	25,0,308,309,5,34,0,0,309,310,3,52,26,0,310,319,1,0,0,0,311,312,3,26,
  	13,0,312,313,5,32,0,0,313,314,3,52,26,0,314,315,3,50,25,0,315,316,5,35,
  	0,0,316,317,3,34,17,0,317,319,1,0,0,0,318,294,1,0,0,0,318,301,1,0,0,0,
  	318,311,1,0,0,0,319,35,1,0,0,0,320,321,3,4,2,0,321,322,5,54,0,0,322,37,
  	1,0,0,0,323,330,3,36,18,0,324,325,3,36,18,0,325,326,5,15,0,0,326,327,
  	3,38,19,0,327,330,1,0,0,0,328,330,5,24,0,0,329,323,1,0,0,0,329,324,1,
  	0,0,0,329,328,1,0,0,0,330,39,1,0,0,0,331,332,5,17,0,0,332,336,3,52,26,
  	0,333,335,3,6,3,0,334,333,1,0,0,0,335,338,1,0,0,0,336,334,1,0,0,0,336,
  	337,1,0,0,0,337,339,1,0,0,0,338,336,1,0,0,0,339,340,5,18,0,0,340,341,
  	3,52,26,0,341,41,1,0,0,0,342,344,3,2,1,0,343,342,1,0,0,0,344,347,1,0,
  	0,0,345,343,1,0,0,0,345,346,1,0,0,0,346,43,1,0,0,0,347,345,1,0,0,0,348,
  	350,5,36,0,0,349,348,1,0,0,0,349,350,1,0,0,0,350,351,1,0,0,0,351,352,
  	5,19,0,0,352,353,5,54,0,0,353,354,5,21,0,0,354,355,3,38,19,0,355,356,
  	5,22,0,0,356,357,3,4,2,0,357,358,3,52,26,0,358,45,1,0,0,0,359,362,3,40,
  	20,0,360,362,3,44,22,0,361,359,1,0,0,0,361,360,1,0,0,0,362,47,1,0,0,0,
  	363,365,5,36,0,0,364,363,1,0,0,0,364,365,1,0,0,0,365,366,1,0,0,0,366,
  	367,5,20,0,0,367,368,5,54,0,0,368,369,5,21,0,0,369,370,3,38,19,0,370,
  	371,5,22,0,0,371,372,3,4,2,0,372,373,3,52,26,0,373,374,3,50,25,0,374,
  	375,5,23,0,0,375,376,3,52,26,0,376,49,1,0,0,0,377,379,3,32,16,0,378,377,
  	1,0,0,0,379,382,1,0,0,0,380,378,1,0,0,0,380,381,1,0,0,0,381,51,1,0,0,
  	0,382,380,1,0,0,0,383,386,3,56,28,0,384,386,5,0,0,1,385,383,1,0,0,0,385,
  	384,1,0,0,0,386,53,1,0,0,0,387,391,3,56,28,0,388,391,5,0,0,1,389,391,
  	1,0,0,0,390,387,1,0,0,0,390,388,1,0,0,0,390,389,1,0,0,0,391,55,1,0,0,
  	0,392,396,5,56,0,0,393,394,5,56,0,0,394,396,3,52,26,0,395,392,1,0,0,0,
  	395,393,1,0,0,0,396,57,1,0,0,0,33,64,70,73,85,88,95,102,115,129,131,143,
  	145,163,165,177,179,190,201,230,242,250,292,318,329,336,345,349,361,364,
  	380,385,390,395
  };
  staticData->serializedATN = antlr4::atn::SerializedATNView(serializedATNSegment, sizeof(serializedATNSegment) / sizeof(serializedATNSegment[0]));

  antlr4::atn::ATNDeserializer deserializer;
  staticData->atn = deserializer.deserialize(staticData->serializedATN);

  const size_t count = staticData->atn->getNumberOfDecisions();
  staticData->decisionToDFA.reserve(count);
  for (size_t i = 0; i < count; i++) { 
    staticData->decisionToDFA.emplace_back(staticData->atn->getDecisionState(i), i);
  }
  jassParserStaticData = std::move(staticData);
}

}

JassParser::JassParser(TokenStream *input) : JassParser(input, antlr4::atn::ParserATNSimulatorOptions()) {}

JassParser::JassParser(TokenStream *input, const antlr4::atn::ParserATNSimulatorOptions &options) : Parser(input) {
  JassParser::initialize();
  _interpreter = new atn::ParserATNSimulator(this, *jassParserStaticData->atn, jassParserStaticData->decisionToDFA, jassParserStaticData->sharedContextCache, options);
}

JassParser::~JassParser() {
  delete _interpreter;
}

const atn::ATN& JassParser::getATN() const {
  return *jassParserStaticData->atn;
}

std::string JassParser::getGrammarFileName() const {
  return "Jass.g4";
}

const std::vector<std::string>& JassParser::getRuleNames() const {
  return jassParserStaticData->ruleNames;
}

const dfa::Vocabulary& JassParser::getVocabulary() const {
  return jassParserStaticData->vocabulary;
}

antlr4::atn::SerializedATNView JassParser::getSerializedATN() const {
  return jassParserStaticData->serializedATN;
}


//----------------- ProgramContext ------------------------------------------------------------------

JassParser::ProgramContext::ProgramContext(ParserRuleContext *parent, size_t invokingState)
  : ParserRuleContext(parent, invokingState) {
}

JassParser::NewlinesContext* JassParser::ProgramContext::newlines() {
  return getRuleContext<JassParser::NewlinesContext>(0);
}

JassParser::Newlines_optContext* JassParser::ProgramContext::newlines_opt() {
  return getRuleContext<JassParser::Newlines_optContext>(0);
}

JassParser::TypeDeclarationBlockContext* JassParser::ProgramContext::typeDeclarationBlock() {
  return getRuleContext<JassParser::TypeDeclarationBlockContext>(0);
}

std::vector<JassParser::BlockContext *> JassParser::ProgramContext::block() {
  return getRuleContexts<JassParser::BlockContext>();
}

JassParser::BlockContext* JassParser::ProgramContext::block(size_t i) {
  return getRuleContext<JassParser::BlockContext>(i);
}

std::vector<JassParser::FunctionBlockContext *> JassParser::ProgramContext::functionBlock() {
  return getRuleContexts<JassParser::FunctionBlockContext>();
}

JassParser::FunctionBlockContext* JassParser::ProgramContext::functionBlock(size_t i) {
  return getRuleContext<JassParser::FunctionBlockContext>(i);
}


size_t JassParser::ProgramContext::getRuleIndex() const {
  return JassParser::RuleProgram;
}

void JassParser::ProgramContext::enterRule(tree::ParseTreeListener *listener) {
  auto parserListener = dynamic_cast<JassListener *>(listener);
  if (parserListener != nullptr)
    parserListener->enterProgram(this);
}

void JassParser::ProgramContext::exitRule(tree::ParseTreeListener *listener) {
  auto parserListener = dynamic_cast<JassListener *>(listener);
  if (parserListener != nullptr)
    parserListener->exitProgram(this);
}


std::any JassParser::ProgramContext::accept(tree::ParseTreeVisitor *visitor) {
  if (auto parserVisitor = dynamic_cast<JassVisitor*>(visitor))
    return parserVisitor->visitProgram(this);
  else
    return visitor->visitChildren(this);
}

JassParser::ProgramContext* JassParser::program() {
  ProgramContext *_localctx = _tracker.createInstance<ProgramContext>(_ctx, getState());
  enterRule(_localctx, 0, JassParser::RuleProgram);
  size_t _la = 0;

#if __cplusplus > 201703L
  auto onExit = finally([=, this] {
#else
  auto onExit = finally([=] {
#endif
    exitRule();
  });
  try {
    size_t alt;
    setState(73);
    _errHandler->sync(this);
    switch (getInterpreter<atn::ParserATNSimulator>()->adaptivePredict(_input, 2, _ctx)) {
    case 1: {
      enterOuterAlt(_localctx, 1);
      setState(58);
      newlines();
      break;
    }

    case 2: {
      enterOuterAlt(_localctx, 2);
      setState(59);
      newlines_opt();
      setState(60);
      typeDeclarationBlock();
      setState(64);
      _errHandler->sync(this);
      alt = getInterpreter<atn::ParserATNSimulator>()->adaptivePredict(_input, 0, _ctx);
      while (alt != 2 && alt != atn::ATN::INVALID_ALT_NUMBER) {
        if (alt == 1) {
          setState(61);
          block(); 
        }
        setState(66);
        _errHandler->sync(this);
        alt = getInterpreter<atn::ParserATNSimulator>()->adaptivePredict(_input, 0, _ctx);
      }
      setState(70);
      _errHandler->sync(this);
      _la = _input->LA(1);
      while (_la == JassParser::FUNCTION

      || _la == JassParser::CONSTANT) {
        setState(67);
        functionBlock();
        setState(72);
        _errHandler->sync(this);
        _la = _input->LA(1);
      }
      break;
    }

    default:
      break;
    }
   
  }
  catch (RecognitionException &e) {
    _errHandler->reportError(this, e);
    _localctx->exception = std::current_exception();
    _errHandler->recover(this, _localctx->exception);
  }

  return _localctx;
}

//----------------- TypeDeclarationContext ------------------------------------------------------------------

JassParser::TypeDeclarationContext::TypeDeclarationContext(ParserRuleContext *parent, size_t invokingState)
  : ParserRuleContext(parent, invokingState) {
}

tree::TerminalNode* JassParser::TypeDeclarationContext::TYPE() {
  return getToken(JassParser::TYPE, 0);
}

std::vector<tree::TerminalNode *> JassParser::TypeDeclarationContext::ID() {
  return getTokens(JassParser::ID);
}

tree::TerminalNode* JassParser::TypeDeclarationContext::ID(size_t i) {
  return getToken(JassParser::ID, i);
}

tree::TerminalNode* JassParser::TypeDeclarationContext::EXTENDS() {
  return getToken(JassParser::EXTENDS, 0);
}

JassParser::NewlinesContext* JassParser::TypeDeclarationContext::newlines() {
  return getRuleContext<JassParser::NewlinesContext>(0);
}


size_t JassParser::TypeDeclarationContext::getRuleIndex() const {
  return JassParser::RuleTypeDeclaration;
}

void JassParser::TypeDeclarationContext::enterRule(tree::ParseTreeListener *listener) {
  auto parserListener = dynamic_cast<JassListener *>(listener);
  if (parserListener != nullptr)
    parserListener->enterTypeDeclaration(this);
}

void JassParser::TypeDeclarationContext::exitRule(tree::ParseTreeListener *listener) {
  auto parserListener = dynamic_cast<JassListener *>(listener);
  if (parserListener != nullptr)
    parserListener->exitTypeDeclaration(this);
}


std::any JassParser::TypeDeclarationContext::accept(tree::ParseTreeVisitor *visitor) {
  if (auto parserVisitor = dynamic_cast<JassVisitor*>(visitor))
    return parserVisitor->visitTypeDeclaration(this);
  else
    return visitor->visitChildren(this);
}

JassParser::TypeDeclarationContext* JassParser::typeDeclaration() {
  TypeDeclarationContext *_localctx = _tracker.createInstance<TypeDeclarationContext>(_ctx, getState());
  enterRule(_localctx, 2, JassParser::RuleTypeDeclaration);

#if __cplusplus > 201703L
  auto onExit = finally([=, this] {
#else
  auto onExit = finally([=] {
#endif
    exitRule();
  });
  try {
    enterOuterAlt(_localctx, 1);
    setState(75);
    match(JassParser::TYPE);
    setState(76);
    match(JassParser::ID);
    setState(77);
    match(JassParser::EXTENDS);
    setState(78);
    match(JassParser::ID);
    setState(79);
    newlines();
   
  }
  catch (RecognitionException &e) {
    _errHandler->reportError(this, e);
    _localctx->exception = std::current_exception();
    _errHandler->recover(this, _localctx->exception);
  }

  return _localctx;
}

//----------------- TypeContext ------------------------------------------------------------------

JassParser::TypeContext::TypeContext(ParserRuleContext *parent, size_t invokingState)
  : ParserRuleContext(parent, invokingState) {
}


size_t JassParser::TypeContext::getRuleIndex() const {
  return JassParser::RuleType;
}

void JassParser::TypeContext::copyFrom(TypeContext *ctx) {
  ParserRuleContext::copyFrom(ctx);
}

//----------------- ArrayTypeContext ------------------------------------------------------------------

tree::TerminalNode* JassParser::ArrayTypeContext::ID() {
  return getToken(JassParser::ID, 0);
}

tree::TerminalNode* JassParser::ArrayTypeContext::ARRAY() {
  return getToken(JassParser::ARRAY, 0);
}

JassParser::ArrayTypeContext::ArrayTypeContext(TypeContext *ctx) { copyFrom(ctx); }

void JassParser::ArrayTypeContext::enterRule(tree::ParseTreeListener *listener) {
  auto parserListener = dynamic_cast<JassListener *>(listener);
  if (parserListener != nullptr)
    parserListener->enterArrayType(this);
}
void JassParser::ArrayTypeContext::exitRule(tree::ParseTreeListener *listener) {
  auto parserListener = dynamic_cast<JassListener *>(listener);
  if (parserListener != nullptr)
    parserListener->exitArrayType(this);
}

std::any JassParser::ArrayTypeContext::accept(tree::ParseTreeVisitor *visitor) {
  if (auto parserVisitor = dynamic_cast<JassVisitor*>(visitor))
    return parserVisitor->visitArrayType(this);
  else
    return visitor->visitChildren(this);
}
//----------------- BasicTypeContext ------------------------------------------------------------------

tree::TerminalNode* JassParser::BasicTypeContext::ID() {
  return getToken(JassParser::ID, 0);
}

JassParser::BasicTypeContext::BasicTypeContext(TypeContext *ctx) { copyFrom(ctx); }

void JassParser::BasicTypeContext::enterRule(tree::ParseTreeListener *listener) {
  auto parserListener = dynamic_cast<JassListener *>(listener);
  if (parserListener != nullptr)
    parserListener->enterBasicType(this);
}
void JassParser::BasicTypeContext::exitRule(tree::ParseTreeListener *listener) {
  auto parserListener = dynamic_cast<JassListener *>(listener);
  if (parserListener != nullptr)
    parserListener->exitBasicType(this);
}

std::any JassParser::BasicTypeContext::accept(tree::ParseTreeVisitor *visitor) {
  if (auto parserVisitor = dynamic_cast<JassVisitor*>(visitor))
    return parserVisitor->visitBasicType(this);
  else
    return visitor->visitChildren(this);
}
//----------------- NothingTypeContext ------------------------------------------------------------------

tree::TerminalNode* JassParser::NothingTypeContext::NOTHING() {
  return getToken(JassParser::NOTHING, 0);
}

JassParser::NothingTypeContext::NothingTypeContext(TypeContext *ctx) { copyFrom(ctx); }

void JassParser::NothingTypeContext::enterRule(tree::ParseTreeListener *listener) {
  auto parserListener = dynamic_cast<JassListener *>(listener);
  if (parserListener != nullptr)
    parserListener->enterNothingType(this);
}
void JassParser::NothingTypeContext::exitRule(tree::ParseTreeListener *listener) {
  auto parserListener = dynamic_cast<JassListener *>(listener);
  if (parserListener != nullptr)
    parserListener->exitNothingType(this);
}

std::any JassParser::NothingTypeContext::accept(tree::ParseTreeVisitor *visitor) {
  if (auto parserVisitor = dynamic_cast<JassVisitor*>(visitor))
    return parserVisitor->visitNothingType(this);
  else
    return visitor->visitChildren(this);
}
JassParser::TypeContext* JassParser::type() {
  TypeContext *_localctx = _tracker.createInstance<TypeContext>(_ctx, getState());
  enterRule(_localctx, 4, JassParser::RuleType);

#if __cplusplus > 201703L
  auto onExit = finally([=, this] {
#else
  auto onExit = finally([=] {
#endif
    exitRule();
  });
  try {
    setState(85);
    _errHandler->sync(this);
    switch (getInterpreter<atn::ParserATNSimulator>()->adaptivePredict(_input, 3, _ctx)) {
    case 1: {
      _localctx = _tracker.createInstance<JassParser::BasicTypeContext>(_localctx);
      enterOuterAlt(_localctx, 1);
      setState(81);
      match(JassParser::ID);
      break;
    }

    case 2: {
      _localctx = _tracker.createInstance<JassParser::ArrayTypeContext>(_localctx);
      enterOuterAlt(_localctx, 2);
      setState(82);
      match(JassParser::ID);
      setState(83);
      match(JassParser::ARRAY);
      break;
    }

    case 3: {
      _localctx = _tracker.createInstance<JassParser::NothingTypeContext>(_localctx);
      enterOuterAlt(_localctx, 3);
      setState(84);
      match(JassParser::NOTHING);
      break;
    }

    default:
      break;
    }
   
  }
  catch (RecognitionException &e) {
    _errHandler->reportError(this, e);
    _localctx->exception = std::current_exception();
    _errHandler->recover(this, _localctx->exception);
  }

  return _localctx;
}

//----------------- GlobalContext ------------------------------------------------------------------

JassParser::GlobalContext::GlobalContext(ParserRuleContext *parent, size_t invokingState)
  : ParserRuleContext(parent, invokingState) {
}


size_t JassParser::GlobalContext::getRuleIndex() const {
  return JassParser::RuleGlobal;
}

void JassParser::GlobalContext::copyFrom(GlobalContext *ctx) {
  ParserRuleContext::copyFrom(ctx);
}

//----------------- DefinitionGlobalContext ------------------------------------------------------------------

JassParser::TypeContext* JassParser::DefinitionGlobalContext::type() {
  return getRuleContext<JassParser::TypeContext>(0);
}

tree::TerminalNode* JassParser::DefinitionGlobalContext::ID() {
  return getToken(JassParser::ID, 0);
}

JassParser::AssignTailContext* JassParser::DefinitionGlobalContext::assignTail() {
  return getRuleContext<JassParser::AssignTailContext>(0);
}

JassParser::NewlinesContext* JassParser::DefinitionGlobalContext::newlines() {
  return getRuleContext<JassParser::NewlinesContext>(0);
}

tree::TerminalNode* JassParser::DefinitionGlobalContext::CONSTANT() {
  return getToken(JassParser::CONSTANT, 0);
}

JassParser::DefinitionGlobalContext::DefinitionGlobalContext(GlobalContext *ctx) { copyFrom(ctx); }

void JassParser::DefinitionGlobalContext::enterRule(tree::ParseTreeListener *listener) {
  auto parserListener = dynamic_cast<JassListener *>(listener);
  if (parserListener != nullptr)
    parserListener->enterDefinitionGlobal(this);
}
void JassParser::DefinitionGlobalContext::exitRule(tree::ParseTreeListener *listener) {
  auto parserListener = dynamic_cast<JassListener *>(listener);
  if (parserListener != nullptr)
    parserListener->exitDefinitionGlobal(this);
}

std::any JassParser::DefinitionGlobalContext::accept(tree::ParseTreeVisitor *visitor) {
  if (auto parserVisitor = dynamic_cast<JassVisitor*>(visitor))
    return parserVisitor->visitDefinitionGlobal(this);
  else
    return visitor->visitChildren(this);
}
//----------------- BasicGlobalContext ------------------------------------------------------------------

JassParser::TypeContext* JassParser::BasicGlobalContext::type() {
  return getRuleContext<JassParser::TypeContext>(0);
}

tree::TerminalNode* JassParser::BasicGlobalContext::ID() {
  return getToken(JassParser::ID, 0);
}

JassParser::NewlinesContext* JassParser::BasicGlobalContext::newlines() {
  return getRuleContext<JassParser::NewlinesContext>(0);
}

tree::TerminalNode* JassParser::BasicGlobalContext::CONSTANT() {
  return getToken(JassParser::CONSTANT, 0);
}

JassParser::BasicGlobalContext::BasicGlobalContext(GlobalContext *ctx) { copyFrom(ctx); }

void JassParser::BasicGlobalContext::enterRule(tree::ParseTreeListener *listener) {
  auto parserListener = dynamic_cast<JassListener *>(listener);
  if (parserListener != nullptr)
    parserListener->enterBasicGlobal(this);
}
void JassParser::BasicGlobalContext::exitRule(tree::ParseTreeListener *listener) {
  auto parserListener = dynamic_cast<JassListener *>(listener);
  if (parserListener != nullptr)
    parserListener->exitBasicGlobal(this);
}

std::any JassParser::BasicGlobalContext::accept(tree::ParseTreeVisitor *visitor) {
  if (auto parserVisitor = dynamic_cast<JassVisitor*>(visitor))
    return parserVisitor->visitBasicGlobal(this);
  else
    return visitor->visitChildren(this);
}
JassParser::GlobalContext* JassParser::global() {
  GlobalContext *_localctx = _tracker.createInstance<GlobalContext>(_ctx, getState());
  enterRule(_localctx, 6, JassParser::RuleGlobal);
  size_t _la = 0;

#if __cplusplus > 201703L
  auto onExit = finally([=, this] {
#else
  auto onExit = finally([=] {
#endif
    exitRule();
  });
  try {
    setState(102);
    _errHandler->sync(this);
    switch (getInterpreter<atn::ParserATNSimulator>()->adaptivePredict(_input, 6, _ctx)) {
    case 1: {
      _localctx = _tracker.createInstance<JassParser::BasicGlobalContext>(_localctx);
      enterOuterAlt(_localctx, 1);
      setState(88);
      _errHandler->sync(this);

      _la = _input->LA(1);
      if (_la == JassParser::CONSTANT) {
        setState(87);
        match(JassParser::CONSTANT);
      }
      setState(90);
      type();
      setState(91);
      match(JassParser::ID);
      setState(92);
      newlines();
      break;
    }

    case 2: {
      _localctx = _tracker.createInstance<JassParser::DefinitionGlobalContext>(_localctx);
      enterOuterAlt(_localctx, 2);
      setState(95);
      _errHandler->sync(this);

      _la = _input->LA(1);
      if (_la == JassParser::CONSTANT) {
        setState(94);
        match(JassParser::CONSTANT);
      }
      setState(97);
      type();
      setState(98);
      match(JassParser::ID);
      setState(99);
      assignTail();
      setState(100);
      newlines();
      break;
    }

    default:
      break;
    }
   
  }
  catch (RecognitionException &e) {
    _errHandler->reportError(this, e);
    _localctx->exception = std::current_exception();
    _errHandler->recover(this, _localctx->exception);
  }

  return _localctx;
}

//----------------- LocalContext ------------------------------------------------------------------

JassParser::LocalContext::LocalContext(ParserRuleContext *parent, size_t invokingState)
  : ParserRuleContext(parent, invokingState) {
}


size_t JassParser::LocalContext::getRuleIndex() const {
  return JassParser::RuleLocal;
}

void JassParser::LocalContext::copyFrom(LocalContext *ctx) {
  ParserRuleContext::copyFrom(ctx);
}

//----------------- BasicLocalContext ------------------------------------------------------------------

tree::TerminalNode* JassParser::BasicLocalContext::LOCAL() {
  return getToken(JassParser::LOCAL, 0);
}

JassParser::TypeContext* JassParser::BasicLocalContext::type() {
  return getRuleContext<JassParser::TypeContext>(0);
}

tree::TerminalNode* JassParser::BasicLocalContext::ID() {
  return getToken(JassParser::ID, 0);
}

JassParser::NewlinesContext* JassParser::BasicLocalContext::newlines() {
  return getRuleContext<JassParser::NewlinesContext>(0);
}

JassParser::BasicLocalContext::BasicLocalContext(LocalContext *ctx) { copyFrom(ctx); }

void JassParser::BasicLocalContext::enterRule(tree::ParseTreeListener *listener) {
  auto parserListener = dynamic_cast<JassListener *>(listener);
  if (parserListener != nullptr)
    parserListener->enterBasicLocal(this);
}
void JassParser::BasicLocalContext::exitRule(tree::ParseTreeListener *listener) {
  auto parserListener = dynamic_cast<JassListener *>(listener);
  if (parserListener != nullptr)
    parserListener->exitBasicLocal(this);
}

std::any JassParser::BasicLocalContext::accept(tree::ParseTreeVisitor *visitor) {
  if (auto parserVisitor = dynamic_cast<JassVisitor*>(visitor))
    return parserVisitor->visitBasicLocal(this);
  else
    return visitor->visitChildren(this);
}
//----------------- DefinitionLocalContext ------------------------------------------------------------------

tree::TerminalNode* JassParser::DefinitionLocalContext::LOCAL() {
  return getToken(JassParser::LOCAL, 0);
}

JassParser::TypeContext* JassParser::DefinitionLocalContext::type() {
  return getRuleContext<JassParser::TypeContext>(0);
}

tree::TerminalNode* JassParser::DefinitionLocalContext::ID() {
  return getToken(JassParser::ID, 0);
}

JassParser::AssignTailContext* JassParser::DefinitionLocalContext::assignTail() {
  return getRuleContext<JassParser::AssignTailContext>(0);
}

JassParser::NewlinesContext* JassParser::DefinitionLocalContext::newlines() {
  return getRuleContext<JassParser::NewlinesContext>(0);
}

JassParser::DefinitionLocalContext::DefinitionLocalContext(LocalContext *ctx) { copyFrom(ctx); }

void JassParser::DefinitionLocalContext::enterRule(tree::ParseTreeListener *listener) {
  auto parserListener = dynamic_cast<JassListener *>(listener);
  if (parserListener != nullptr)
    parserListener->enterDefinitionLocal(this);
}
void JassParser::DefinitionLocalContext::exitRule(tree::ParseTreeListener *listener) {
  auto parserListener = dynamic_cast<JassListener *>(listener);
  if (parserListener != nullptr)
    parserListener->exitDefinitionLocal(this);
}

std::any JassParser::DefinitionLocalContext::accept(tree::ParseTreeVisitor *visitor) {
  if (auto parserVisitor = dynamic_cast<JassVisitor*>(visitor))
    return parserVisitor->visitDefinitionLocal(this);
  else
    return visitor->visitChildren(this);
}
JassParser::LocalContext* JassParser::local() {
  LocalContext *_localctx = _tracker.createInstance<LocalContext>(_ctx, getState());
  enterRule(_localctx, 8, JassParser::RuleLocal);

#if __cplusplus > 201703L
  auto onExit = finally([=, this] {
#else
  auto onExit = finally([=] {
#endif
    exitRule();
  });
  try {
    setState(115);
    _errHandler->sync(this);
    switch (getInterpreter<atn::ParserATNSimulator>()->adaptivePredict(_input, 7, _ctx)) {
    case 1: {
      _localctx = _tracker.createInstance<JassParser::BasicLocalContext>(_localctx);
      enterOuterAlt(_localctx, 1);
      setState(104);
      match(JassParser::LOCAL);
      setState(105);
      type();
      setState(106);
      match(JassParser::ID);
      setState(107);
      newlines();
      break;
    }

    case 2: {
      _localctx = _tracker.createInstance<JassParser::DefinitionLocalContext>(_localctx);
      enterOuterAlt(_localctx, 2);
      setState(109);
      match(JassParser::LOCAL);
      setState(110);
      type();
      setState(111);
      match(JassParser::ID);
      setState(112);
      assignTail();
      setState(113);
      newlines();
      break;
    }

    default:
      break;
    }
   
  }
  catch (RecognitionException &e) {
    _errHandler->reportError(this, e);
    _localctx->exception = std::current_exception();
    _errHandler->recover(this, _localctx->exception);
  }

  return _localctx;
}

//----------------- AssignTailContext ------------------------------------------------------------------

JassParser::AssignTailContext::AssignTailContext(ParserRuleContext *parent, size_t invokingState)
  : ParserRuleContext(parent, invokingState) {
}

tree::TerminalNode* JassParser::AssignTailContext::EQUALS() {
  return getToken(JassParser::EQUALS, 0);
}

JassParser::ExpressionContext* JassParser::AssignTailContext::expression() {
  return getRuleContext<JassParser::ExpressionContext>(0);
}


size_t JassParser::AssignTailContext::getRuleIndex() const {
  return JassParser::RuleAssignTail;
}

void JassParser::AssignTailContext::enterRule(tree::ParseTreeListener *listener) {
  auto parserListener = dynamic_cast<JassListener *>(listener);
  if (parserListener != nullptr)
    parserListener->enterAssignTail(this);
}

void JassParser::AssignTailContext::exitRule(tree::ParseTreeListener *listener) {
  auto parserListener = dynamic_cast<JassListener *>(listener);
  if (parserListener != nullptr)
    parserListener->exitAssignTail(this);
}


std::any JassParser::AssignTailContext::accept(tree::ParseTreeVisitor *visitor) {
  if (auto parserVisitor = dynamic_cast<JassVisitor*>(visitor))
    return parserVisitor->visitAssignTail(this);
  else
    return visitor->visitChildren(this);
}

JassParser::AssignTailContext* JassParser::assignTail() {
  AssignTailContext *_localctx = _tracker.createInstance<AssignTailContext>(_ctx, getState());
  enterRule(_localctx, 10, JassParser::RuleAssignTail);

#if __cplusplus > 201703L
  auto onExit = finally([=, this] {
#else
  auto onExit = finally([=] {
#endif
    exitRule();
  });
  try {
    enterOuterAlt(_localctx, 1);
    setState(117);
    match(JassParser::EQUALS);
    setState(118);
    expression();
   
  }
  catch (RecognitionException &e) {
    _errHandler->reportError(this, e);
    _localctx->exception = std::current_exception();
    _errHandler->recover(this, _localctx->exception);
  }

  return _localctx;
}

//----------------- MultDivExpressionContext ------------------------------------------------------------------

JassParser::MultDivExpressionContext::MultDivExpressionContext(ParserRuleContext *parent, size_t invokingState)
  : ParserRuleContext(parent, invokingState) {
}


size_t JassParser::MultDivExpressionContext::getRuleIndex() const {
  return JassParser::RuleMultDivExpression;
}

void JassParser::MultDivExpressionContext::copyFrom(MultDivExpressionContext *ctx) {
  ParserRuleContext::copyFrom(ctx);
}

//----------------- BaseMultiplicationExpressionContext ------------------------------------------------------------------

JassParser::BaseExpressionContext* JassParser::BaseMultiplicationExpressionContext::baseExpression() {
  return getRuleContext<JassParser::BaseExpressionContext>(0);
}

JassParser::BaseMultiplicationExpressionContext::BaseMultiplicationExpressionContext(MultDivExpressionContext *ctx) { copyFrom(ctx); }

void JassParser::BaseMultiplicationExpressionContext::enterRule(tree::ParseTreeListener *listener) {
  auto parserListener = dynamic_cast<JassListener *>(listener);
  if (parserListener != nullptr)
    parserListener->enterBaseMultiplicationExpression(this);
}
void JassParser::BaseMultiplicationExpressionContext::exitRule(tree::ParseTreeListener *listener) {
  auto parserListener = dynamic_cast<JassListener *>(listener);
  if (parserListener != nullptr)
    parserListener->exitBaseMultiplicationExpression(this);
}

std::any JassParser::BaseMultiplicationExpressionContext::accept(tree::ParseTreeVisitor *visitor) {
  if (auto parserVisitor = dynamic_cast<JassVisitor*>(visitor))
    return parserVisitor->visitBaseMultiplicationExpression(this);
  else
    return visitor->visitChildren(this);
}
//----------------- DivisionExpressionContext ------------------------------------------------------------------

JassParser::MultDivExpressionContext* JassParser::DivisionExpressionContext::multDivExpression() {
  return getRuleContext<JassParser::MultDivExpressionContext>(0);
}

JassParser::BaseExpressionContext* JassParser::DivisionExpressionContext::baseExpression() {
  return getRuleContext<JassParser::BaseExpressionContext>(0);
}

JassParser::DivisionExpressionContext::DivisionExpressionContext(MultDivExpressionContext *ctx) { copyFrom(ctx); }

void JassParser::DivisionExpressionContext::enterRule(tree::ParseTreeListener *listener) {
  auto parserListener = dynamic_cast<JassListener *>(listener);
  if (parserListener != nullptr)
    parserListener->enterDivisionExpression(this);
}
void JassParser::DivisionExpressionContext::exitRule(tree::ParseTreeListener *listener) {
  auto parserListener = dynamic_cast<JassListener *>(listener);
  if (parserListener != nullptr)
    parserListener->exitDivisionExpression(this);
}

std::any JassParser::DivisionExpressionContext::accept(tree::ParseTreeVisitor *visitor) {
  if (auto parserVisitor = dynamic_cast<JassVisitor*>(visitor))
    return parserVisitor->visitDivisionExpression(this);
  else
    return visitor->visitChildren(this);
}
//----------------- MultiplicationExpressionContext ------------------------------------------------------------------

JassParser::MultDivExpressionContext* JassParser::MultiplicationExpressionContext::multDivExpression() {
  return getRuleContext<JassParser::MultDivExpressionContext>(0);
}

JassParser::BaseExpressionContext* JassParser::MultiplicationExpressionContext::baseExpression() {
  return getRuleContext<JassParser::BaseExpressionContext>(0);
}

JassParser::MultiplicationExpressionContext::MultiplicationExpressionContext(MultDivExpressionContext *ctx) { copyFrom(ctx); }

void JassParser::MultiplicationExpressionContext::enterRule(tree::ParseTreeListener *listener) {
  auto parserListener = dynamic_cast<JassListener *>(listener);
  if (parserListener != nullptr)
    parserListener->enterMultiplicationExpression(this);
}
void JassParser::MultiplicationExpressionContext::exitRule(tree::ParseTreeListener *listener) {
  auto parserListener = dynamic_cast<JassListener *>(listener);
  if (parserListener != nullptr)
    parserListener->exitMultiplicationExpression(this);
}

std::any JassParser::MultiplicationExpressionContext::accept(tree::ParseTreeVisitor *visitor) {
  if (auto parserVisitor = dynamic_cast<JassVisitor*>(visitor))
    return parserVisitor->visitMultiplicationExpression(this);
  else
    return visitor->visitChildren(this);
}

JassParser::MultDivExpressionContext* JassParser::multDivExpression() {
   return multDivExpression(0);
}

JassParser::MultDivExpressionContext* JassParser::multDivExpression(int precedence) {
  ParserRuleContext *parentContext = _ctx;
  size_t parentState = getState();
  JassParser::MultDivExpressionContext *_localctx = _tracker.createInstance<MultDivExpressionContext>(_ctx, parentState);
  JassParser::MultDivExpressionContext *previousContext = _localctx;
  (void)previousContext; // Silence compiler, in case the context is not used by generated code.
  size_t startState = 12;
  enterRecursionRule(_localctx, 12, JassParser::RuleMultDivExpression, precedence);

    

#if __cplusplus > 201703L
  auto onExit = finally([=, this] {
#else
  auto onExit = finally([=] {
#endif
    unrollRecursionContexts(parentContext);
  });
  try {
    size_t alt;
    enterOuterAlt(_localctx, 1);
    _localctx = _tracker.createInstance<BaseMultiplicationExpressionContext>(_localctx);
    _ctx = _localctx;
    previousContext = _localctx;

    setState(121);
    baseExpression();
    _ctx->stop = _input->LT(-1);
    setState(131);
    _errHandler->sync(this);
    alt = getInterpreter<atn::ParserATNSimulator>()->adaptivePredict(_input, 9, _ctx);
    while (alt != 2 && alt != atn::ATN::INVALID_ALT_NUMBER) {
      if (alt == 1) {
        if (!_parseListeners.empty())
          triggerExitRuleEvent();
        previousContext = _localctx;
        setState(129);
        _errHandler->sync(this);
        switch (getInterpreter<atn::ParserATNSimulator>()->adaptivePredict(_input, 8, _ctx)) {
        case 1: {
          auto newContext = _tracker.createInstance<MultiplicationExpressionContext>(_tracker.createInstance<MultDivExpressionContext>(parentContext, parentState));
          _localctx = newContext;
          pushNewRecursionContext(newContext, startState, RuleMultDivExpression);
          setState(123);

          if (!(precpred(_ctx, 3))) throw FailedPredicateException(this, "precpred(_ctx, 3)");
          setState(124);
          match(JassParser::T__0);
          setState(125);
          baseExpression();
          break;
        }

        case 2: {
          auto newContext = _tracker.createInstance<DivisionExpressionContext>(_tracker.createInstance<MultDivExpressionContext>(parentContext, parentState));
          _localctx = newContext;
          pushNewRecursionContext(newContext, startState, RuleMultDivExpression);
          setState(126);

          if (!(precpred(_ctx, 2))) throw FailedPredicateException(this, "precpred(_ctx, 2)");
          setState(127);
          match(JassParser::T__1);
          setState(128);
          baseExpression();
          break;
        }

        default:
          break;
        } 
      }
      setState(133);
      _errHandler->sync(this);
      alt = getInterpreter<atn::ParserATNSimulator>()->adaptivePredict(_input, 9, _ctx);
    }
  }
  catch (RecognitionException &e) {
    _errHandler->reportError(this, e);
    _localctx->exception = std::current_exception();
    _errHandler->recover(this, _localctx->exception);
  }
  return _localctx;
}

//----------------- SimpleArithmeticExpressionContext ------------------------------------------------------------------

JassParser::SimpleArithmeticExpressionContext::SimpleArithmeticExpressionContext(ParserRuleContext *parent, size_t invokingState)
  : ParserRuleContext(parent, invokingState) {
}


size_t JassParser::SimpleArithmeticExpressionContext::getRuleIndex() const {
  return JassParser::RuleSimpleArithmeticExpression;
}

void JassParser::SimpleArithmeticExpressionContext::copyFrom(SimpleArithmeticExpressionContext *ctx) {
  ParserRuleContext::copyFrom(ctx);
}

//----------------- AdditionExpressionContext ------------------------------------------------------------------

JassParser::SimpleArithmeticExpressionContext* JassParser::AdditionExpressionContext::simpleArithmeticExpression() {
  return getRuleContext<JassParser::SimpleArithmeticExpressionContext>(0);
}

JassParser::MultDivExpressionContext* JassParser::AdditionExpressionContext::multDivExpression() {
  return getRuleContext<JassParser::MultDivExpressionContext>(0);
}

JassParser::AdditionExpressionContext::AdditionExpressionContext(SimpleArithmeticExpressionContext *ctx) { copyFrom(ctx); }

void JassParser::AdditionExpressionContext::enterRule(tree::ParseTreeListener *listener) {
  auto parserListener = dynamic_cast<JassListener *>(listener);
  if (parserListener != nullptr)
    parserListener->enterAdditionExpression(this);
}
void JassParser::AdditionExpressionContext::exitRule(tree::ParseTreeListener *listener) {
  auto parserListener = dynamic_cast<JassListener *>(listener);
  if (parserListener != nullptr)
    parserListener->exitAdditionExpression(this);
}

std::any JassParser::AdditionExpressionContext::accept(tree::ParseTreeVisitor *visitor) {
  if (auto parserVisitor = dynamic_cast<JassVisitor*>(visitor))
    return parserVisitor->visitAdditionExpression(this);
  else
    return visitor->visitChildren(this);
}
//----------------- SubtrationExpressionContext ------------------------------------------------------------------

JassParser::SimpleArithmeticExpressionContext* JassParser::SubtrationExpressionContext::simpleArithmeticExpression() {
  return getRuleContext<JassParser::SimpleArithmeticExpressionContext>(0);
}

JassParser::MultDivExpressionContext* JassParser::SubtrationExpressionContext::multDivExpression() {
  return getRuleContext<JassParser::MultDivExpressionContext>(0);
}

JassParser::SubtrationExpressionContext::SubtrationExpressionContext(SimpleArithmeticExpressionContext *ctx) { copyFrom(ctx); }

void JassParser::SubtrationExpressionContext::enterRule(tree::ParseTreeListener *listener) {
  auto parserListener = dynamic_cast<JassListener *>(listener);
  if (parserListener != nullptr)
    parserListener->enterSubtrationExpression(this);
}
void JassParser::SubtrationExpressionContext::exitRule(tree::ParseTreeListener *listener) {
  auto parserListener = dynamic_cast<JassListener *>(listener);
  if (parserListener != nullptr)
    parserListener->exitSubtrationExpression(this);
}

std::any JassParser::SubtrationExpressionContext::accept(tree::ParseTreeVisitor *visitor) {
  if (auto parserVisitor = dynamic_cast<JassVisitor*>(visitor))
    return parserVisitor->visitSubtrationExpression(this);
  else
    return visitor->visitChildren(this);
}
//----------------- BaseAdditionExpressionContext ------------------------------------------------------------------

JassParser::MultDivExpressionContext* JassParser::BaseAdditionExpressionContext::multDivExpression() {
  return getRuleContext<JassParser::MultDivExpressionContext>(0);
}

JassParser::BaseAdditionExpressionContext::BaseAdditionExpressionContext(SimpleArithmeticExpressionContext *ctx) { copyFrom(ctx); }

void JassParser::BaseAdditionExpressionContext::enterRule(tree::ParseTreeListener *listener) {
  auto parserListener = dynamic_cast<JassListener *>(listener);
  if (parserListener != nullptr)
    parserListener->enterBaseAdditionExpression(this);
}
void JassParser::BaseAdditionExpressionContext::exitRule(tree::ParseTreeListener *listener) {
  auto parserListener = dynamic_cast<JassListener *>(listener);
  if (parserListener != nullptr)
    parserListener->exitBaseAdditionExpression(this);
}

std::any JassParser::BaseAdditionExpressionContext::accept(tree::ParseTreeVisitor *visitor) {
  if (auto parserVisitor = dynamic_cast<JassVisitor*>(visitor))
    return parserVisitor->visitBaseAdditionExpression(this);
  else
    return visitor->visitChildren(this);
}

JassParser::SimpleArithmeticExpressionContext* JassParser::simpleArithmeticExpression() {
   return simpleArithmeticExpression(0);
}

JassParser::SimpleArithmeticExpressionContext* JassParser::simpleArithmeticExpression(int precedence) {
  ParserRuleContext *parentContext = _ctx;
  size_t parentState = getState();
  JassParser::SimpleArithmeticExpressionContext *_localctx = _tracker.createInstance<SimpleArithmeticExpressionContext>(_ctx, parentState);
  JassParser::SimpleArithmeticExpressionContext *previousContext = _localctx;
  (void)previousContext; // Silence compiler, in case the context is not used by generated code.
  size_t startState = 14;
  enterRecursionRule(_localctx, 14, JassParser::RuleSimpleArithmeticExpression, precedence);

    

#if __cplusplus > 201703L
  auto onExit = finally([=, this] {
#else
  auto onExit = finally([=] {
#endif
    unrollRecursionContexts(parentContext);
  });
  try {
    size_t alt;
    enterOuterAlt(_localctx, 1);
    _localctx = _tracker.createInstance<BaseAdditionExpressionContext>(_localctx);
    _ctx = _localctx;
    previousContext = _localctx;

    setState(135);
    multDivExpression(0);
    _ctx->stop = _input->LT(-1);
    setState(145);
    _errHandler->sync(this);
    alt = getInterpreter<atn::ParserATNSimulator>()->adaptivePredict(_input, 11, _ctx);
    while (alt != 2 && alt != atn::ATN::INVALID_ALT_NUMBER) {
      if (alt == 1) {
        if (!_parseListeners.empty())
          triggerExitRuleEvent();
        previousContext = _localctx;
        setState(143);
        _errHandler->sync(this);
        switch (getInterpreter<atn::ParserATNSimulator>()->adaptivePredict(_input, 10, _ctx)) {
        case 1: {
          auto newContext = _tracker.createInstance<AdditionExpressionContext>(_tracker.createInstance<SimpleArithmeticExpressionContext>(parentContext, parentState));
          _localctx = newContext;
          pushNewRecursionContext(newContext, startState, RuleSimpleArithmeticExpression);
          setState(137);

          if (!(precpred(_ctx, 3))) throw FailedPredicateException(this, "precpred(_ctx, 3)");
          setState(138);
          match(JassParser::T__2);
          setState(139);
          multDivExpression(0);
          break;
        }

        case 2: {
          auto newContext = _tracker.createInstance<SubtrationExpressionContext>(_tracker.createInstance<SimpleArithmeticExpressionContext>(parentContext, parentState));
          _localctx = newContext;
          pushNewRecursionContext(newContext, startState, RuleSimpleArithmeticExpression);
          setState(140);

          if (!(precpred(_ctx, 2))) throw FailedPredicateException(this, "precpred(_ctx, 2)");
          setState(141);
          match(JassParser::T__3);
          setState(142);
          multDivExpression(0);
          break;
        }

        default:
          break;
        } 
      }
      setState(147);
      _errHandler->sync(this);
      alt = getInterpreter<atn::ParserATNSimulator>()->adaptivePredict(_input, 11, _ctx);
    }
  }
  catch (RecognitionException &e) {
    _errHandler->reportError(this, e);
    _localctx->exception = std::current_exception();
    _errHandler->recover(this, _localctx->exception);
  }
  return _localctx;
}

//----------------- BoolComparisonExpressionContext ------------------------------------------------------------------

JassParser::BoolComparisonExpressionContext::BoolComparisonExpressionContext(ParserRuleContext *parent, size_t invokingState)
  : ParserRuleContext(parent, invokingState) {
}


size_t JassParser::BoolComparisonExpressionContext::getRuleIndex() const {
  return JassParser::RuleBoolComparisonExpression;
}

void JassParser::BoolComparisonExpressionContext::copyFrom(BoolComparisonExpressionContext *ctx) {
  ParserRuleContext::copyFrom(ctx);
}

//----------------- BooleanLessExpressionContext ------------------------------------------------------------------

JassParser::BoolComparisonExpressionContext* JassParser::BooleanLessExpressionContext::boolComparisonExpression() {
  return getRuleContext<JassParser::BoolComparisonExpressionContext>(0);
}

JassParser::SimpleArithmeticExpressionContext* JassParser::BooleanLessExpressionContext::simpleArithmeticExpression() {
  return getRuleContext<JassParser::SimpleArithmeticExpressionContext>(0);
}

JassParser::BooleanLessExpressionContext::BooleanLessExpressionContext(BoolComparisonExpressionContext *ctx) { copyFrom(ctx); }

void JassParser::BooleanLessExpressionContext::enterRule(tree::ParseTreeListener *listener) {
  auto parserListener = dynamic_cast<JassListener *>(listener);
  if (parserListener != nullptr)
    parserListener->enterBooleanLessExpression(this);
}
void JassParser::BooleanLessExpressionContext::exitRule(tree::ParseTreeListener *listener) {
  auto parserListener = dynamic_cast<JassListener *>(listener);
  if (parserListener != nullptr)
    parserListener->exitBooleanLessExpression(this);
}

std::any JassParser::BooleanLessExpressionContext::accept(tree::ParseTreeVisitor *visitor) {
  if (auto parserVisitor = dynamic_cast<JassVisitor*>(visitor))
    return parserVisitor->visitBooleanLessExpression(this);
  else
    return visitor->visitChildren(this);
}
//----------------- BooleanGreaterExpressionContext ------------------------------------------------------------------

JassParser::BoolComparisonExpressionContext* JassParser::BooleanGreaterExpressionContext::boolComparisonExpression() {
  return getRuleContext<JassParser::BoolComparisonExpressionContext>(0);
}

JassParser::SimpleArithmeticExpressionContext* JassParser::BooleanGreaterExpressionContext::simpleArithmeticExpression() {
  return getRuleContext<JassParser::SimpleArithmeticExpressionContext>(0);
}

JassParser::BooleanGreaterExpressionContext::BooleanGreaterExpressionContext(BoolComparisonExpressionContext *ctx) { copyFrom(ctx); }

void JassParser::BooleanGreaterExpressionContext::enterRule(tree::ParseTreeListener *listener) {
  auto parserListener = dynamic_cast<JassListener *>(listener);
  if (parserListener != nullptr)
    parserListener->enterBooleanGreaterExpression(this);
}
void JassParser::BooleanGreaterExpressionContext::exitRule(tree::ParseTreeListener *listener) {
  auto parserListener = dynamic_cast<JassListener *>(listener);
  if (parserListener != nullptr)
    parserListener->exitBooleanGreaterExpression(this);
}

std::any JassParser::BooleanGreaterExpressionContext::accept(tree::ParseTreeVisitor *visitor) {
  if (auto parserVisitor = dynamic_cast<JassVisitor*>(visitor))
    return parserVisitor->visitBooleanGreaterExpression(this);
  else
    return visitor->visitChildren(this);
}
//----------------- BaseBoolComparisonExpressionContext ------------------------------------------------------------------

JassParser::SimpleArithmeticExpressionContext* JassParser::BaseBoolComparisonExpressionContext::simpleArithmeticExpression() {
  return getRuleContext<JassParser::SimpleArithmeticExpressionContext>(0);
}

JassParser::BaseBoolComparisonExpressionContext::BaseBoolComparisonExpressionContext(BoolComparisonExpressionContext *ctx) { copyFrom(ctx); }

void JassParser::BaseBoolComparisonExpressionContext::enterRule(tree::ParseTreeListener *listener) {
  auto parserListener = dynamic_cast<JassListener *>(listener);
  if (parserListener != nullptr)
    parserListener->enterBaseBoolComparisonExpression(this);
}
void JassParser::BaseBoolComparisonExpressionContext::exitRule(tree::ParseTreeListener *listener) {
  auto parserListener = dynamic_cast<JassListener *>(listener);
  if (parserListener != nullptr)
    parserListener->exitBaseBoolComparisonExpression(this);
}

std::any JassParser::BaseBoolComparisonExpressionContext::accept(tree::ParseTreeVisitor *visitor) {
  if (auto parserVisitor = dynamic_cast<JassVisitor*>(visitor))
    return parserVisitor->visitBaseBoolComparisonExpression(this);
  else
    return visitor->visitChildren(this);
}
//----------------- BooleanLessOrEqualsExpressionContext ------------------------------------------------------------------

JassParser::BoolComparisonExpressionContext* JassParser::BooleanLessOrEqualsExpressionContext::boolComparisonExpression() {
  return getRuleContext<JassParser::BoolComparisonExpressionContext>(0);
}

JassParser::SimpleArithmeticExpressionContext* JassParser::BooleanLessOrEqualsExpressionContext::simpleArithmeticExpression() {
  return getRuleContext<JassParser::SimpleArithmeticExpressionContext>(0);
}

JassParser::BooleanLessOrEqualsExpressionContext::BooleanLessOrEqualsExpressionContext(BoolComparisonExpressionContext *ctx) { copyFrom(ctx); }

void JassParser::BooleanLessOrEqualsExpressionContext::enterRule(tree::ParseTreeListener *listener) {
  auto parserListener = dynamic_cast<JassListener *>(listener);
  if (parserListener != nullptr)
    parserListener->enterBooleanLessOrEqualsExpression(this);
}
void JassParser::BooleanLessOrEqualsExpressionContext::exitRule(tree::ParseTreeListener *listener) {
  auto parserListener = dynamic_cast<JassListener *>(listener);
  if (parserListener != nullptr)
    parserListener->exitBooleanLessOrEqualsExpression(this);
}

std::any JassParser::BooleanLessOrEqualsExpressionContext::accept(tree::ParseTreeVisitor *visitor) {
  if (auto parserVisitor = dynamic_cast<JassVisitor*>(visitor))
    return parserVisitor->visitBooleanLessOrEqualsExpression(this);
  else
    return visitor->visitChildren(this);
}
//----------------- BooleanGreaterOrEqualsExpressionContext ------------------------------------------------------------------

JassParser::BoolComparisonExpressionContext* JassParser::BooleanGreaterOrEqualsExpressionContext::boolComparisonExpression() {
  return getRuleContext<JassParser::BoolComparisonExpressionContext>(0);
}

JassParser::SimpleArithmeticExpressionContext* JassParser::BooleanGreaterOrEqualsExpressionContext::simpleArithmeticExpression() {
  return getRuleContext<JassParser::SimpleArithmeticExpressionContext>(0);
}

JassParser::BooleanGreaterOrEqualsExpressionContext::BooleanGreaterOrEqualsExpressionContext(BoolComparisonExpressionContext *ctx) { copyFrom(ctx); }

void JassParser::BooleanGreaterOrEqualsExpressionContext::enterRule(tree::ParseTreeListener *listener) {
  auto parserListener = dynamic_cast<JassListener *>(listener);
  if (parserListener != nullptr)
    parserListener->enterBooleanGreaterOrEqualsExpression(this);
}
void JassParser::BooleanGreaterOrEqualsExpressionContext::exitRule(tree::ParseTreeListener *listener) {
  auto parserListener = dynamic_cast<JassListener *>(listener);
  if (parserListener != nullptr)
    parserListener->exitBooleanGreaterOrEqualsExpression(this);
}

std::any JassParser::BooleanGreaterOrEqualsExpressionContext::accept(tree::ParseTreeVisitor *visitor) {
  if (auto parserVisitor = dynamic_cast<JassVisitor*>(visitor))
    return parserVisitor->visitBooleanGreaterOrEqualsExpression(this);
  else
    return visitor->visitChildren(this);
}

JassParser::BoolComparisonExpressionContext* JassParser::boolComparisonExpression() {
   return boolComparisonExpression(0);
}

JassParser::BoolComparisonExpressionContext* JassParser::boolComparisonExpression(int precedence) {
  ParserRuleContext *parentContext = _ctx;
  size_t parentState = getState();
  JassParser::BoolComparisonExpressionContext *_localctx = _tracker.createInstance<BoolComparisonExpressionContext>(_ctx, parentState);
  JassParser::BoolComparisonExpressionContext *previousContext = _localctx;
  (void)previousContext; // Silence compiler, in case the context is not used by generated code.
  size_t startState = 16;
  enterRecursionRule(_localctx, 16, JassParser::RuleBoolComparisonExpression, precedence);

    

#if __cplusplus > 201703L
  auto onExit = finally([=, this] {
#else
  auto onExit = finally([=] {
#endif
    unrollRecursionContexts(parentContext);
  });
  try {
    size_t alt;
    enterOuterAlt(_localctx, 1);
    _localctx = _tracker.createInstance<BaseBoolComparisonExpressionContext>(_localctx);
    _ctx = _localctx;
    previousContext = _localctx;

    setState(149);
    simpleArithmeticExpression(0);
    _ctx->stop = _input->LT(-1);
    setState(165);
    _errHandler->sync(this);
    alt = getInterpreter<atn::ParserATNSimulator>()->adaptivePredict(_input, 13, _ctx);
    while (alt != 2 && alt != atn::ATN::INVALID_ALT_NUMBER) {
      if (alt == 1) {
        if (!_parseListeners.empty())
          triggerExitRuleEvent();
        previousContext = _localctx;
        setState(163);
        _errHandler->sync(this);
        switch (getInterpreter<atn::ParserATNSimulator>()->adaptivePredict(_input, 12, _ctx)) {
        case 1: {
          auto newContext = _tracker.createInstance<BooleanLessExpressionContext>(_tracker.createInstance<BoolComparisonExpressionContext>(parentContext, parentState));
          _localctx = newContext;
          pushNewRecursionContext(newContext, startState, RuleBoolComparisonExpression);
          setState(151);

          if (!(precpred(_ctx, 5))) throw FailedPredicateException(this, "precpred(_ctx, 5)");
          setState(152);
          match(JassParser::T__4);
          setState(153);
          simpleArithmeticExpression(0);
          break;
        }

        case 2: {
          auto newContext = _tracker.createInstance<BooleanGreaterExpressionContext>(_tracker.createInstance<BoolComparisonExpressionContext>(parentContext, parentState));
          _localctx = newContext;
          pushNewRecursionContext(newContext, startState, RuleBoolComparisonExpression);
          setState(154);

          if (!(precpred(_ctx, 4))) throw FailedPredicateException(this, "precpred(_ctx, 4)");
          setState(155);
          match(JassParser::T__5);
          setState(156);
          simpleArithmeticExpression(0);
          break;
        }

        case 3: {
          auto newContext = _tracker.createInstance<BooleanLessOrEqualsExpressionContext>(_tracker.createInstance<BoolComparisonExpressionContext>(parentContext, parentState));
          _localctx = newContext;
          pushNewRecursionContext(newContext, startState, RuleBoolComparisonExpression);
          setState(157);

          if (!(precpred(_ctx, 3))) throw FailedPredicateException(this, "precpred(_ctx, 3)");
          setState(158);
          match(JassParser::T__6);
          setState(159);
          simpleArithmeticExpression(0);
          break;
        }

        case 4: {
          auto newContext = _tracker.createInstance<BooleanGreaterOrEqualsExpressionContext>(_tracker.createInstance<BoolComparisonExpressionContext>(parentContext, parentState));
          _localctx = newContext;
          pushNewRecursionContext(newContext, startState, RuleBoolComparisonExpression);
          setState(160);

          if (!(precpred(_ctx, 2))) throw FailedPredicateException(this, "precpred(_ctx, 2)");
          setState(161);
          match(JassParser::T__7);
          setState(162);
          simpleArithmeticExpression(0);
          break;
        }

        default:
          break;
        } 
      }
      setState(167);
      _errHandler->sync(this);
      alt = getInterpreter<atn::ParserATNSimulator>()->adaptivePredict(_input, 13, _ctx);
    }
  }
  catch (RecognitionException &e) {
    _errHandler->reportError(this, e);
    _localctx->exception = std::current_exception();
    _errHandler->recover(this, _localctx->exception);
  }
  return _localctx;
}

//----------------- BoolEqualityExpressionContext ------------------------------------------------------------------

JassParser::BoolEqualityExpressionContext::BoolEqualityExpressionContext(ParserRuleContext *parent, size_t invokingState)
  : ParserRuleContext(parent, invokingState) {
}


size_t JassParser::BoolEqualityExpressionContext::getRuleIndex() const {
  return JassParser::RuleBoolEqualityExpression;
}

void JassParser::BoolEqualityExpressionContext::copyFrom(BoolEqualityExpressionContext *ctx) {
  ParserRuleContext::copyFrom(ctx);
}

//----------------- NotEqualsExpressionContext ------------------------------------------------------------------

JassParser::BoolEqualityExpressionContext* JassParser::NotEqualsExpressionContext::boolEqualityExpression() {
  return getRuleContext<JassParser::BoolEqualityExpressionContext>(0);
}

JassParser::BoolComparisonExpressionContext* JassParser::NotEqualsExpressionContext::boolComparisonExpression() {
  return getRuleContext<JassParser::BoolComparisonExpressionContext>(0);
}

JassParser::NotEqualsExpressionContext::NotEqualsExpressionContext(BoolEqualityExpressionContext *ctx) { copyFrom(ctx); }

void JassParser::NotEqualsExpressionContext::enterRule(tree::ParseTreeListener *listener) {
  auto parserListener = dynamic_cast<JassListener *>(listener);
  if (parserListener != nullptr)
    parserListener->enterNotEqualsExpression(this);
}
void JassParser::NotEqualsExpressionContext::exitRule(tree::ParseTreeListener *listener) {
  auto parserListener = dynamic_cast<JassListener *>(listener);
  if (parserListener != nullptr)
    parserListener->exitNotEqualsExpression(this);
}

std::any JassParser::NotEqualsExpressionContext::accept(tree::ParseTreeVisitor *visitor) {
  if (auto parserVisitor = dynamic_cast<JassVisitor*>(visitor))
    return parserVisitor->visitNotEqualsExpression(this);
  else
    return visitor->visitChildren(this);
}
//----------------- BaseBoolExpressionContext ------------------------------------------------------------------

JassParser::BoolComparisonExpressionContext* JassParser::BaseBoolExpressionContext::boolComparisonExpression() {
  return getRuleContext<JassParser::BoolComparisonExpressionContext>(0);
}

JassParser::BaseBoolExpressionContext::BaseBoolExpressionContext(BoolEqualityExpressionContext *ctx) { copyFrom(ctx); }

void JassParser::BaseBoolExpressionContext::enterRule(tree::ParseTreeListener *listener) {
  auto parserListener = dynamic_cast<JassListener *>(listener);
  if (parserListener != nullptr)
    parserListener->enterBaseBoolExpression(this);
}
void JassParser::BaseBoolExpressionContext::exitRule(tree::ParseTreeListener *listener) {
  auto parserListener = dynamic_cast<JassListener *>(listener);
  if (parserListener != nullptr)
    parserListener->exitBaseBoolExpression(this);
}

std::any JassParser::BaseBoolExpressionContext::accept(tree::ParseTreeVisitor *visitor) {
  if (auto parserVisitor = dynamic_cast<JassVisitor*>(visitor))
    return parserVisitor->visitBaseBoolExpression(this);
  else
    return visitor->visitChildren(this);
}
//----------------- EqualsExpressionContext ------------------------------------------------------------------

JassParser::BoolEqualityExpressionContext* JassParser::EqualsExpressionContext::boolEqualityExpression() {
  return getRuleContext<JassParser::BoolEqualityExpressionContext>(0);
}

JassParser::BoolComparisonExpressionContext* JassParser::EqualsExpressionContext::boolComparisonExpression() {
  return getRuleContext<JassParser::BoolComparisonExpressionContext>(0);
}

JassParser::EqualsExpressionContext::EqualsExpressionContext(BoolEqualityExpressionContext *ctx) { copyFrom(ctx); }

void JassParser::EqualsExpressionContext::enterRule(tree::ParseTreeListener *listener) {
  auto parserListener = dynamic_cast<JassListener *>(listener);
  if (parserListener != nullptr)
    parserListener->enterEqualsExpression(this);
}
void JassParser::EqualsExpressionContext::exitRule(tree::ParseTreeListener *listener) {
  auto parserListener = dynamic_cast<JassListener *>(listener);
  if (parserListener != nullptr)
    parserListener->exitEqualsExpression(this);
}

std::any JassParser::EqualsExpressionContext::accept(tree::ParseTreeVisitor *visitor) {
  if (auto parserVisitor = dynamic_cast<JassVisitor*>(visitor))
    return parserVisitor->visitEqualsExpression(this);
  else
    return visitor->visitChildren(this);
}

JassParser::BoolEqualityExpressionContext* JassParser::boolEqualityExpression() {
   return boolEqualityExpression(0);
}

JassParser::BoolEqualityExpressionContext* JassParser::boolEqualityExpression(int precedence) {
  ParserRuleContext *parentContext = _ctx;
  size_t parentState = getState();
  JassParser::BoolEqualityExpressionContext *_localctx = _tracker.createInstance<BoolEqualityExpressionContext>(_ctx, parentState);
  JassParser::BoolEqualityExpressionContext *previousContext = _localctx;
  (void)previousContext; // Silence compiler, in case the context is not used by generated code.
  size_t startState = 18;
  enterRecursionRule(_localctx, 18, JassParser::RuleBoolEqualityExpression, precedence);

    

#if __cplusplus > 201703L
  auto onExit = finally([=, this] {
#else
  auto onExit = finally([=] {
#endif
    unrollRecursionContexts(parentContext);
  });
  try {
    size_t alt;
    enterOuterAlt(_localctx, 1);
    _localctx = _tracker.createInstance<BaseBoolExpressionContext>(_localctx);
    _ctx = _localctx;
    previousContext = _localctx;

    setState(169);
    boolComparisonExpression(0);
    _ctx->stop = _input->LT(-1);
    setState(179);
    _errHandler->sync(this);
    alt = getInterpreter<atn::ParserATNSimulator>()->adaptivePredict(_input, 15, _ctx);
    while (alt != 2 && alt != atn::ATN::INVALID_ALT_NUMBER) {
      if (alt == 1) {
        if (!_parseListeners.empty())
          triggerExitRuleEvent();
        previousContext = _localctx;
        setState(177);
        _errHandler->sync(this);
        switch (getInterpreter<atn::ParserATNSimulator>()->adaptivePredict(_input, 14, _ctx)) {
        case 1: {
          auto newContext = _tracker.createInstance<EqualsExpressionContext>(_tracker.createInstance<BoolEqualityExpressionContext>(parentContext, parentState));
          _localctx = newContext;
          pushNewRecursionContext(newContext, startState, RuleBoolEqualityExpression);
          setState(171);

          if (!(precpred(_ctx, 3))) throw FailedPredicateException(this, "precpred(_ctx, 3)");
          setState(172);
          match(JassParser::T__8);
          setState(173);
          boolComparisonExpression(0);
          break;
        }

        case 2: {
          auto newContext = _tracker.createInstance<NotEqualsExpressionContext>(_tracker.createInstance<BoolEqualityExpressionContext>(parentContext, parentState));
          _localctx = newContext;
          pushNewRecursionContext(newContext, startState, RuleBoolEqualityExpression);
          setState(174);

          if (!(precpred(_ctx, 2))) throw FailedPredicateException(this, "precpred(_ctx, 2)");
          setState(175);
          match(JassParser::T__9);
          setState(176);
          boolComparisonExpression(0);
          break;
        }

        default:
          break;
        } 
      }
      setState(181);
      _errHandler->sync(this);
      alt = getInterpreter<atn::ParserATNSimulator>()->adaptivePredict(_input, 15, _ctx);
    }
  }
  catch (RecognitionException &e) {
    _errHandler->reportError(this, e);
    _localctx->exception = std::current_exception();
    _errHandler->recover(this, _localctx->exception);
  }
  return _localctx;
}

//----------------- BoolAndsExpressionContext ------------------------------------------------------------------

JassParser::BoolAndsExpressionContext::BoolAndsExpressionContext(ParserRuleContext *parent, size_t invokingState)
  : ParserRuleContext(parent, invokingState) {
}


size_t JassParser::BoolAndsExpressionContext::getRuleIndex() const {
  return JassParser::RuleBoolAndsExpression;
}

void JassParser::BoolAndsExpressionContext::copyFrom(BoolAndsExpressionContext *ctx) {
  ParserRuleContext::copyFrom(ctx);
}

//----------------- BaseBoolAndsExpressionContext ------------------------------------------------------------------

JassParser::BoolEqualityExpressionContext* JassParser::BaseBoolAndsExpressionContext::boolEqualityExpression() {
  return getRuleContext<JassParser::BoolEqualityExpressionContext>(0);
}

JassParser::BaseBoolAndsExpressionContext::BaseBoolAndsExpressionContext(BoolAndsExpressionContext *ctx) { copyFrom(ctx); }

void JassParser::BaseBoolAndsExpressionContext::enterRule(tree::ParseTreeListener *listener) {
  auto parserListener = dynamic_cast<JassListener *>(listener);
  if (parserListener != nullptr)
    parserListener->enterBaseBoolAndsExpression(this);
}
void JassParser::BaseBoolAndsExpressionContext::exitRule(tree::ParseTreeListener *listener) {
  auto parserListener = dynamic_cast<JassListener *>(listener);
  if (parserListener != nullptr)
    parserListener->exitBaseBoolAndsExpression(this);
}

std::any JassParser::BaseBoolAndsExpressionContext::accept(tree::ParseTreeVisitor *visitor) {
  if (auto parserVisitor = dynamic_cast<JassVisitor*>(visitor))
    return parserVisitor->visitBaseBoolAndsExpression(this);
  else
    return visitor->visitChildren(this);
}
//----------------- BooleanAndExpressionContext ------------------------------------------------------------------

JassParser::BoolAndsExpressionContext* JassParser::BooleanAndExpressionContext::boolAndsExpression() {
  return getRuleContext<JassParser::BoolAndsExpressionContext>(0);
}

tree::TerminalNode* JassParser::BooleanAndExpressionContext::AND() {
  return getToken(JassParser::AND, 0);
}

JassParser::BoolEqualityExpressionContext* JassParser::BooleanAndExpressionContext::boolEqualityExpression() {
  return getRuleContext<JassParser::BoolEqualityExpressionContext>(0);
}

JassParser::BooleanAndExpressionContext::BooleanAndExpressionContext(BoolAndsExpressionContext *ctx) { copyFrom(ctx); }

void JassParser::BooleanAndExpressionContext::enterRule(tree::ParseTreeListener *listener) {
  auto parserListener = dynamic_cast<JassListener *>(listener);
  if (parserListener != nullptr)
    parserListener->enterBooleanAndExpression(this);
}
void JassParser::BooleanAndExpressionContext::exitRule(tree::ParseTreeListener *listener) {
  auto parserListener = dynamic_cast<JassListener *>(listener);
  if (parserListener != nullptr)
    parserListener->exitBooleanAndExpression(this);
}

std::any JassParser::BooleanAndExpressionContext::accept(tree::ParseTreeVisitor *visitor) {
  if (auto parserVisitor = dynamic_cast<JassVisitor*>(visitor))
    return parserVisitor->visitBooleanAndExpression(this);
  else
    return visitor->visitChildren(this);
}

JassParser::BoolAndsExpressionContext* JassParser::boolAndsExpression() {
   return boolAndsExpression(0);
}

JassParser::BoolAndsExpressionContext* JassParser::boolAndsExpression(int precedence) {
  ParserRuleContext *parentContext = _ctx;
  size_t parentState = getState();
  JassParser::BoolAndsExpressionContext *_localctx = _tracker.createInstance<BoolAndsExpressionContext>(_ctx, parentState);
  JassParser::BoolAndsExpressionContext *previousContext = _localctx;
  (void)previousContext; // Silence compiler, in case the context is not used by generated code.
  size_t startState = 20;
  enterRecursionRule(_localctx, 20, JassParser::RuleBoolAndsExpression, precedence);

    

#if __cplusplus > 201703L
  auto onExit = finally([=, this] {
#else
  auto onExit = finally([=] {
#endif
    unrollRecursionContexts(parentContext);
  });
  try {
    size_t alt;
    enterOuterAlt(_localctx, 1);
    _localctx = _tracker.createInstance<BaseBoolAndsExpressionContext>(_localctx);
    _ctx = _localctx;
    previousContext = _localctx;

    setState(183);
    boolEqualityExpression(0);
    _ctx->stop = _input->LT(-1);
    setState(190);
    _errHandler->sync(this);
    alt = getInterpreter<atn::ParserATNSimulator>()->adaptivePredict(_input, 16, _ctx);
    while (alt != 2 && alt != atn::ATN::INVALID_ALT_NUMBER) {
      if (alt == 1) {
        if (!_parseListeners.empty())
          triggerExitRuleEvent();
        previousContext = _localctx;
        auto newContext = _tracker.createInstance<BooleanAndExpressionContext>(_tracker.createInstance<BoolAndsExpressionContext>(parentContext, parentState));
        _localctx = newContext;
        pushNewRecursionContext(newContext, startState, RuleBoolAndsExpression);
        setState(185);

        if (!(precpred(_ctx, 2))) throw FailedPredicateException(this, "precpred(_ctx, 2)");
        setState(186);
        match(JassParser::AND);
        setState(187);
        boolEqualityExpression(0); 
      }
      setState(192);
      _errHandler->sync(this);
      alt = getInterpreter<atn::ParserATNSimulator>()->adaptivePredict(_input, 16, _ctx);
    }
  }
  catch (RecognitionException &e) {
    _errHandler->reportError(this, e);
    _localctx->exception = std::current_exception();
    _errHandler->recover(this, _localctx->exception);
  }
  return _localctx;
}

//----------------- BoolExpressionContext ------------------------------------------------------------------

JassParser::BoolExpressionContext::BoolExpressionContext(ParserRuleContext *parent, size_t invokingState)
  : ParserRuleContext(parent, invokingState) {
}


size_t JassParser::BoolExpressionContext::getRuleIndex() const {
  return JassParser::RuleBoolExpression;
}

void JassParser::BoolExpressionContext::copyFrom(BoolExpressionContext *ctx) {
  ParserRuleContext::copyFrom(ctx);
}

//----------------- BaseBoolOrsExpressionContext ------------------------------------------------------------------

JassParser::BoolAndsExpressionContext* JassParser::BaseBoolOrsExpressionContext::boolAndsExpression() {
  return getRuleContext<JassParser::BoolAndsExpressionContext>(0);
}

JassParser::BaseBoolOrsExpressionContext::BaseBoolOrsExpressionContext(BoolExpressionContext *ctx) { copyFrom(ctx); }

void JassParser::BaseBoolOrsExpressionContext::enterRule(tree::ParseTreeListener *listener) {
  auto parserListener = dynamic_cast<JassListener *>(listener);
  if (parserListener != nullptr)
    parserListener->enterBaseBoolOrsExpression(this);
}
void JassParser::BaseBoolOrsExpressionContext::exitRule(tree::ParseTreeListener *listener) {
  auto parserListener = dynamic_cast<JassListener *>(listener);
  if (parserListener != nullptr)
    parserListener->exitBaseBoolOrsExpression(this);
}

std::any JassParser::BaseBoolOrsExpressionContext::accept(tree::ParseTreeVisitor *visitor) {
  if (auto parserVisitor = dynamic_cast<JassVisitor*>(visitor))
    return parserVisitor->visitBaseBoolOrsExpression(this);
  else
    return visitor->visitChildren(this);
}
//----------------- BooleanOrExpressionContext ------------------------------------------------------------------

JassParser::BoolExpressionContext* JassParser::BooleanOrExpressionContext::boolExpression() {
  return getRuleContext<JassParser::BoolExpressionContext>(0);
}

tree::TerminalNode* JassParser::BooleanOrExpressionContext::OR() {
  return getToken(JassParser::OR, 0);
}

JassParser::BoolAndsExpressionContext* JassParser::BooleanOrExpressionContext::boolAndsExpression() {
  return getRuleContext<JassParser::BoolAndsExpressionContext>(0);
}

JassParser::BooleanOrExpressionContext::BooleanOrExpressionContext(BoolExpressionContext *ctx) { copyFrom(ctx); }

void JassParser::BooleanOrExpressionContext::enterRule(tree::ParseTreeListener *listener) {
  auto parserListener = dynamic_cast<JassListener *>(listener);
  if (parserListener != nullptr)
    parserListener->enterBooleanOrExpression(this);
}
void JassParser::BooleanOrExpressionContext::exitRule(tree::ParseTreeListener *listener) {
  auto parserListener = dynamic_cast<JassListener *>(listener);
  if (parserListener != nullptr)
    parserListener->exitBooleanOrExpression(this);
}

std::any JassParser::BooleanOrExpressionContext::accept(tree::ParseTreeVisitor *visitor) {
  if (auto parserVisitor = dynamic_cast<JassVisitor*>(visitor))
    return parserVisitor->visitBooleanOrExpression(this);
  else
    return visitor->visitChildren(this);
}

JassParser::BoolExpressionContext* JassParser::boolExpression() {
   return boolExpression(0);
}

JassParser::BoolExpressionContext* JassParser::boolExpression(int precedence) {
  ParserRuleContext *parentContext = _ctx;
  size_t parentState = getState();
  JassParser::BoolExpressionContext *_localctx = _tracker.createInstance<BoolExpressionContext>(_ctx, parentState);
  JassParser::BoolExpressionContext *previousContext = _localctx;
  (void)previousContext; // Silence compiler, in case the context is not used by generated code.
  size_t startState = 22;
  enterRecursionRule(_localctx, 22, JassParser::RuleBoolExpression, precedence);

    

#if __cplusplus > 201703L
  auto onExit = finally([=, this] {
#else
  auto onExit = finally([=] {
#endif
    unrollRecursionContexts(parentContext);
  });
  try {
    size_t alt;
    enterOuterAlt(_localctx, 1);
    _localctx = _tracker.createInstance<BaseBoolOrsExpressionContext>(_localctx);
    _ctx = _localctx;
    previousContext = _localctx;

    setState(194);
    boolAndsExpression(0);
    _ctx->stop = _input->LT(-1);
    setState(201);
    _errHandler->sync(this);
    alt = getInterpreter<atn::ParserATNSimulator>()->adaptivePredict(_input, 17, _ctx);
    while (alt != 2 && alt != atn::ATN::INVALID_ALT_NUMBER) {
      if (alt == 1) {
        if (!_parseListeners.empty())
          triggerExitRuleEvent();
        previousContext = _localctx;
        auto newContext = _tracker.createInstance<BooleanOrExpressionContext>(_tracker.createInstance<BoolExpressionContext>(parentContext, parentState));
        _localctx = newContext;
        pushNewRecursionContext(newContext, startState, RuleBoolExpression);
        setState(196);

        if (!(precpred(_ctx, 2))) throw FailedPredicateException(this, "precpred(_ctx, 2)");
        setState(197);
        match(JassParser::OR);
        setState(198);
        boolAndsExpression(0); 
      }
      setState(203);
      _errHandler->sync(this);
      alt = getInterpreter<atn::ParserATNSimulator>()->adaptivePredict(_input, 17, _ctx);
    }
  }
  catch (RecognitionException &e) {
    _errHandler->reportError(this, e);
    _localctx->exception = std::current_exception();
    _errHandler->recover(this, _localctx->exception);
  }
  return _localctx;
}

//----------------- BaseExpressionContext ------------------------------------------------------------------

JassParser::BaseExpressionContext::BaseExpressionContext(ParserRuleContext *parent, size_t invokingState)
  : ParserRuleContext(parent, invokingState) {
}


size_t JassParser::BaseExpressionContext::getRuleIndex() const {
  return JassParser::RuleBaseExpression;
}

void JassParser::BaseExpressionContext::copyFrom(BaseExpressionContext *ctx) {
  ParserRuleContext::copyFrom(ctx);
}

//----------------- ParentheticalExpressionContext ------------------------------------------------------------------

JassParser::ExpressionContext* JassParser::ParentheticalExpressionContext::expression() {
  return getRuleContext<JassParser::ExpressionContext>(0);
}

JassParser::ParentheticalExpressionContext::ParentheticalExpressionContext(BaseExpressionContext *ctx) { copyFrom(ctx); }

void JassParser::ParentheticalExpressionContext::enterRule(tree::ParseTreeListener *listener) {
  auto parserListener = dynamic_cast<JassListener *>(listener);
  if (parserListener != nullptr)
    parserListener->enterParentheticalExpression(this);
}
void JassParser::ParentheticalExpressionContext::exitRule(tree::ParseTreeListener *listener) {
  auto parserListener = dynamic_cast<JassListener *>(listener);
  if (parserListener != nullptr)
    parserListener->exitParentheticalExpression(this);
}

std::any JassParser::ParentheticalExpressionContext::accept(tree::ParseTreeVisitor *visitor) {
  if (auto parserVisitor = dynamic_cast<JassVisitor*>(visitor))
    return parserVisitor->visitParentheticalExpression(this);
  else
    return visitor->visitChildren(this);
}
//----------------- StringLiteralExpressionContext ------------------------------------------------------------------

tree::TerminalNode* JassParser::StringLiteralExpressionContext::STRING_LITERAL() {
  return getToken(JassParser::STRING_LITERAL, 0);
}

JassParser::StringLiteralExpressionContext::StringLiteralExpressionContext(BaseExpressionContext *ctx) { copyFrom(ctx); }

void JassParser::StringLiteralExpressionContext::enterRule(tree::ParseTreeListener *listener) {
  auto parserListener = dynamic_cast<JassListener *>(listener);
  if (parserListener != nullptr)
    parserListener->enterStringLiteralExpression(this);
}
void JassParser::StringLiteralExpressionContext::exitRule(tree::ParseTreeListener *listener) {
  auto parserListener = dynamic_cast<JassListener *>(listener);
  if (parserListener != nullptr)
    parserListener->exitStringLiteralExpression(this);
}

std::any JassParser::StringLiteralExpressionContext::accept(tree::ParseTreeVisitor *visitor) {
  if (auto parserVisitor = dynamic_cast<JassVisitor*>(visitor))
    return parserVisitor->visitStringLiteralExpression(this);
  else
    return visitor->visitChildren(this);
}
//----------------- DollarHexIntegerLiteralExpressionContext ------------------------------------------------------------------

tree::TerminalNode* JassParser::DollarHexIntegerLiteralExpressionContext::DOLLAR_HEX_CONSTANT() {
  return getToken(JassParser::DOLLAR_HEX_CONSTANT, 0);
}

JassParser::DollarHexIntegerLiteralExpressionContext::DollarHexIntegerLiteralExpressionContext(BaseExpressionContext *ctx) { copyFrom(ctx); }

void JassParser::DollarHexIntegerLiteralExpressionContext::enterRule(tree::ParseTreeListener *listener) {
  auto parserListener = dynamic_cast<JassListener *>(listener);
  if (parserListener != nullptr)
    parserListener->enterDollarHexIntegerLiteralExpression(this);
}
void JassParser::DollarHexIntegerLiteralExpressionContext::exitRule(tree::ParseTreeListener *listener) {
  auto parserListener = dynamic_cast<JassListener *>(listener);
  if (parserListener != nullptr)
    parserListener->exitDollarHexIntegerLiteralExpression(this);
}

std::any JassParser::DollarHexIntegerLiteralExpressionContext::accept(tree::ParseTreeVisitor *visitor) {
  if (auto parserVisitor = dynamic_cast<JassVisitor*>(visitor))
    return parserVisitor->visitDollarHexIntegerLiteralExpression(this);
  else
    return visitor->visitChildren(this);
}
//----------------- FunctionReferenceExpressionContext ------------------------------------------------------------------

tree::TerminalNode* JassParser::FunctionReferenceExpressionContext::FUNCTION() {
  return getToken(JassParser::FUNCTION, 0);
}

tree::TerminalNode* JassParser::FunctionReferenceExpressionContext::ID() {
  return getToken(JassParser::ID, 0);
}

JassParser::FunctionReferenceExpressionContext::FunctionReferenceExpressionContext(BaseExpressionContext *ctx) { copyFrom(ctx); }

void JassParser::FunctionReferenceExpressionContext::enterRule(tree::ParseTreeListener *listener) {
  auto parserListener = dynamic_cast<JassListener *>(listener);
  if (parserListener != nullptr)
    parserListener->enterFunctionReferenceExpression(this);
}
void JassParser::FunctionReferenceExpressionContext::exitRule(tree::ParseTreeListener *listener) {
  auto parserListener = dynamic_cast<JassListener *>(listener);
  if (parserListener != nullptr)
    parserListener->exitFunctionReferenceExpression(this);
}

std::any JassParser::FunctionReferenceExpressionContext::accept(tree::ParseTreeVisitor *visitor) {
  if (auto parserVisitor = dynamic_cast<JassVisitor*>(visitor))
    return parserVisitor->visitFunctionReferenceExpression(this);
  else
    return visitor->visitChildren(this);
}
//----------------- HexIntegerLiteralExpressionContext ------------------------------------------------------------------

tree::TerminalNode* JassParser::HexIntegerLiteralExpressionContext::HEX_CONSTANT() {
  return getToken(JassParser::HEX_CONSTANT, 0);
}

JassParser::HexIntegerLiteralExpressionContext::HexIntegerLiteralExpressionContext(BaseExpressionContext *ctx) { copyFrom(ctx); }

void JassParser::HexIntegerLiteralExpressionContext::enterRule(tree::ParseTreeListener *listener) {
  auto parserListener = dynamic_cast<JassListener *>(listener);
  if (parserListener != nullptr)
    parserListener->enterHexIntegerLiteralExpression(this);
}
void JassParser::HexIntegerLiteralExpressionContext::exitRule(tree::ParseTreeListener *listener) {
  auto parserListener = dynamic_cast<JassListener *>(listener);
  if (parserListener != nullptr)
    parserListener->exitHexIntegerLiteralExpression(this);
}

std::any JassParser::HexIntegerLiteralExpressionContext::accept(tree::ParseTreeVisitor *visitor) {
  if (auto parserVisitor = dynamic_cast<JassVisitor*>(visitor))
    return parserVisitor->visitHexIntegerLiteralExpression(this);
  else
    return visitor->visitChildren(this);
}
//----------------- NotExpressionContext ------------------------------------------------------------------

tree::TerminalNode* JassParser::NotExpressionContext::NOT() {
  return getToken(JassParser::NOT, 0);
}

JassParser::BaseExpressionContext* JassParser::NotExpressionContext::baseExpression() {
  return getRuleContext<JassParser::BaseExpressionContext>(0);
}

JassParser::NotExpressionContext::NotExpressionContext(BaseExpressionContext *ctx) { copyFrom(ctx); }

void JassParser::NotExpressionContext::enterRule(tree::ParseTreeListener *listener) {
  auto parserListener = dynamic_cast<JassListener *>(listener);
  if (parserListener != nullptr)
    parserListener->enterNotExpression(this);
}
void JassParser::NotExpressionContext::exitRule(tree::ParseTreeListener *listener) {
  auto parserListener = dynamic_cast<JassListener *>(listener);
  if (parserListener != nullptr)
    parserListener->exitNotExpression(this);
}

std::any JassParser::NotExpressionContext::accept(tree::ParseTreeVisitor *visitor) {
  if (auto parserVisitor = dynamic_cast<JassVisitor*>(visitor))
    return parserVisitor->visitNotExpression(this);
  else
    return visitor->visitChildren(this);
}
//----------------- FunctionCallExpressionContext ------------------------------------------------------------------

JassParser::FunctionExpressionContext* JassParser::FunctionCallExpressionContext::functionExpression() {
  return getRuleContext<JassParser::FunctionExpressionContext>(0);
}

JassParser::FunctionCallExpressionContext::FunctionCallExpressionContext(BaseExpressionContext *ctx) { copyFrom(ctx); }

void JassParser::FunctionCallExpressionContext::enterRule(tree::ParseTreeListener *listener) {
  auto parserListener = dynamic_cast<JassListener *>(listener);
  if (parserListener != nullptr)
    parserListener->enterFunctionCallExpression(this);
}
void JassParser::FunctionCallExpressionContext::exitRule(tree::ParseTreeListener *listener) {
  auto parserListener = dynamic_cast<JassListener *>(listener);
  if (parserListener != nullptr)
    parserListener->exitFunctionCallExpression(this);
}

std::any JassParser::FunctionCallExpressionContext::accept(tree::ParseTreeVisitor *visitor) {
  if (auto parserVisitor = dynamic_cast<JassVisitor*>(visitor))
    return parserVisitor->visitFunctionCallExpression(this);
  else
    return visitor->visitChildren(this);
}
//----------------- NullExpressionContext ------------------------------------------------------------------

tree::TerminalNode* JassParser::NullExpressionContext::NULL_() {
  return getToken(JassParser::NULL_, 0);
}

JassParser::NullExpressionContext::NullExpressionContext(BaseExpressionContext *ctx) { copyFrom(ctx); }

void JassParser::NullExpressionContext::enterRule(tree::ParseTreeListener *listener) {
  auto parserListener = dynamic_cast<JassListener *>(listener);
  if (parserListener != nullptr)
    parserListener->enterNullExpression(this);
}
void JassParser::NullExpressionContext::exitRule(tree::ParseTreeListener *listener) {
  auto parserListener = dynamic_cast<JassListener *>(listener);
  if (parserListener != nullptr)
    parserListener->exitNullExpression(this);
}

std::any JassParser::NullExpressionContext::accept(tree::ParseTreeVisitor *visitor) {
  if (auto parserVisitor = dynamic_cast<JassVisitor*>(visitor))
    return parserVisitor->visitNullExpression(this);
  else
    return visitor->visitChildren(this);
}
//----------------- NegateExpressionContext ------------------------------------------------------------------

JassParser::BaseExpressionContext* JassParser::NegateExpressionContext::baseExpression() {
  return getRuleContext<JassParser::BaseExpressionContext>(0);
}

JassParser::NegateExpressionContext::NegateExpressionContext(BaseExpressionContext *ctx) { copyFrom(ctx); }

void JassParser::NegateExpressionContext::enterRule(tree::ParseTreeListener *listener) {
  auto parserListener = dynamic_cast<JassListener *>(listener);
  if (parserListener != nullptr)
    parserListener->enterNegateExpression(this);
}
void JassParser::NegateExpressionContext::exitRule(tree::ParseTreeListener *listener) {
  auto parserListener = dynamic_cast<JassListener *>(listener);
  if (parserListener != nullptr)
    parserListener->exitNegateExpression(this);
}

std::any JassParser::NegateExpressionContext::accept(tree::ParseTreeVisitor *visitor) {
  if (auto parserVisitor = dynamic_cast<JassVisitor*>(visitor))
    return parserVisitor->visitNegateExpression(this);
  else
    return visitor->visitChildren(this);
}
//----------------- RawcodeLiteralExpressionContext ------------------------------------------------------------------

tree::TerminalNode* JassParser::RawcodeLiteralExpressionContext::RAWCODE() {
  return getToken(JassParser::RAWCODE, 0);
}

JassParser::RawcodeLiteralExpressionContext::RawcodeLiteralExpressionContext(BaseExpressionContext *ctx) { copyFrom(ctx); }

void JassParser::RawcodeLiteralExpressionContext::enterRule(tree::ParseTreeListener *listener) {
  auto parserListener = dynamic_cast<JassListener *>(listener);
  if (parserListener != nullptr)
    parserListener->enterRawcodeLiteralExpression(this);
}
void JassParser::RawcodeLiteralExpressionContext::exitRule(tree::ParseTreeListener *listener) {
  auto parserListener = dynamic_cast<JassListener *>(listener);
  if (parserListener != nullptr)
    parserListener->exitRawcodeLiteralExpression(this);
}

std::any JassParser::RawcodeLiteralExpressionContext::accept(tree::ParseTreeVisitor *visitor) {
  if (auto parserVisitor = dynamic_cast<JassVisitor*>(visitor))
    return parserVisitor->visitRawcodeLiteralExpression(this);
  else
    return visitor->visitChildren(this);
}
//----------------- TrueExpressionContext ------------------------------------------------------------------

tree::TerminalNode* JassParser::TrueExpressionContext::TRUE() {
  return getToken(JassParser::TRUE, 0);
}

JassParser::TrueExpressionContext::TrueExpressionContext(BaseExpressionContext *ctx) { copyFrom(ctx); }

void JassParser::TrueExpressionContext::enterRule(tree::ParseTreeListener *listener) {
  auto parserListener = dynamic_cast<JassListener *>(listener);
  if (parserListener != nullptr)
    parserListener->enterTrueExpression(this);
}
void JassParser::TrueExpressionContext::exitRule(tree::ParseTreeListener *listener) {
  auto parserListener = dynamic_cast<JassListener *>(listener);
  if (parserListener != nullptr)
    parserListener->exitTrueExpression(this);
}

std::any JassParser::TrueExpressionContext::accept(tree::ParseTreeVisitor *visitor) {
  if (auto parserVisitor = dynamic_cast<JassVisitor*>(visitor))
    return parserVisitor->visitTrueExpression(this);
  else
    return visitor->visitChildren(this);
}
//----------------- IntegerLiteralExpressionContext ------------------------------------------------------------------

tree::TerminalNode* JassParser::IntegerLiteralExpressionContext::INTEGER() {
  return getToken(JassParser::INTEGER, 0);
}

JassParser::IntegerLiteralExpressionContext::IntegerLiteralExpressionContext(BaseExpressionContext *ctx) { copyFrom(ctx); }

void JassParser::IntegerLiteralExpressionContext::enterRule(tree::ParseTreeListener *listener) {
  auto parserListener = dynamic_cast<JassListener *>(listener);
  if (parserListener != nullptr)
    parserListener->enterIntegerLiteralExpression(this);
}
void JassParser::IntegerLiteralExpressionContext::exitRule(tree::ParseTreeListener *listener) {
  auto parserListener = dynamic_cast<JassListener *>(listener);
  if (parserListener != nullptr)
    parserListener->exitIntegerLiteralExpression(this);
}

std::any JassParser::IntegerLiteralExpressionContext::accept(tree::ParseTreeVisitor *visitor) {
  if (auto parserVisitor = dynamic_cast<JassVisitor*>(visitor))
    return parserVisitor->visitIntegerLiteralExpression(this);
  else
    return visitor->visitChildren(this);
}
//----------------- ReferenceExpressionContext ------------------------------------------------------------------

tree::TerminalNode* JassParser::ReferenceExpressionContext::ID() {
  return getToken(JassParser::ID, 0);
}

JassParser::ReferenceExpressionContext::ReferenceExpressionContext(BaseExpressionContext *ctx) { copyFrom(ctx); }

void JassParser::ReferenceExpressionContext::enterRule(tree::ParseTreeListener *listener) {
  auto parserListener = dynamic_cast<JassListener *>(listener);
  if (parserListener != nullptr)
    parserListener->enterReferenceExpression(this);
}
void JassParser::ReferenceExpressionContext::exitRule(tree::ParseTreeListener *listener) {
  auto parserListener = dynamic_cast<JassListener *>(listener);
  if (parserListener != nullptr)
    parserListener->exitReferenceExpression(this);
}

std::any JassParser::ReferenceExpressionContext::accept(tree::ParseTreeVisitor *visitor) {
  if (auto parserVisitor = dynamic_cast<JassVisitor*>(visitor))
    return parserVisitor->visitReferenceExpression(this);
  else
    return visitor->visitChildren(this);
}
//----------------- RealLiteralExpressionContext ------------------------------------------------------------------

tree::TerminalNode* JassParser::RealLiteralExpressionContext::REAL() {
  return getToken(JassParser::REAL, 0);
}

JassParser::RealLiteralExpressionContext::RealLiteralExpressionContext(BaseExpressionContext *ctx) { copyFrom(ctx); }

void JassParser::RealLiteralExpressionContext::enterRule(tree::ParseTreeListener *listener) {
  auto parserListener = dynamic_cast<JassListener *>(listener);
  if (parserListener != nullptr)
    parserListener->enterRealLiteralExpression(this);
}
void JassParser::RealLiteralExpressionContext::exitRule(tree::ParseTreeListener *listener) {
  auto parserListener = dynamic_cast<JassListener *>(listener);
  if (parserListener != nullptr)
    parserListener->exitRealLiteralExpression(this);
}

std::any JassParser::RealLiteralExpressionContext::accept(tree::ParseTreeVisitor *visitor) {
  if (auto parserVisitor = dynamic_cast<JassVisitor*>(visitor))
    return parserVisitor->visitRealLiteralExpression(this);
  else
    return visitor->visitChildren(this);
}
//----------------- ArrayReferenceExpressionContext ------------------------------------------------------------------

tree::TerminalNode* JassParser::ArrayReferenceExpressionContext::ID() {
  return getToken(JassParser::ID, 0);
}

JassParser::ExpressionContext* JassParser::ArrayReferenceExpressionContext::expression() {
  return getRuleContext<JassParser::ExpressionContext>(0);
}

JassParser::ArrayReferenceExpressionContext::ArrayReferenceExpressionContext(BaseExpressionContext *ctx) { copyFrom(ctx); }

void JassParser::ArrayReferenceExpressionContext::enterRule(tree::ParseTreeListener *listener) {
  auto parserListener = dynamic_cast<JassListener *>(listener);
  if (parserListener != nullptr)
    parserListener->enterArrayReferenceExpression(this);
}
void JassParser::ArrayReferenceExpressionContext::exitRule(tree::ParseTreeListener *listener) {
  auto parserListener = dynamic_cast<JassListener *>(listener);
  if (parserListener != nullptr)
    parserListener->exitArrayReferenceExpression(this);
}

std::any JassParser::ArrayReferenceExpressionContext::accept(tree::ParseTreeVisitor *visitor) {
  if (auto parserVisitor = dynamic_cast<JassVisitor*>(visitor))
    return parserVisitor->visitArrayReferenceExpression(this);
  else
    return visitor->visitChildren(this);
}
//----------------- FalseExpressionContext ------------------------------------------------------------------

tree::TerminalNode* JassParser::FalseExpressionContext::FALSE() {
  return getToken(JassParser::FALSE, 0);
}

JassParser::FalseExpressionContext::FalseExpressionContext(BaseExpressionContext *ctx) { copyFrom(ctx); }

void JassParser::FalseExpressionContext::enterRule(tree::ParseTreeListener *listener) {
  auto parserListener = dynamic_cast<JassListener *>(listener);
  if (parserListener != nullptr)
    parserListener->enterFalseExpression(this);
}
void JassParser::FalseExpressionContext::exitRule(tree::ParseTreeListener *listener) {
  auto parserListener = dynamic_cast<JassListener *>(listener);
  if (parserListener != nullptr)
    parserListener->exitFalseExpression(this);
}

std::any JassParser::FalseExpressionContext::accept(tree::ParseTreeVisitor *visitor) {
  if (auto parserVisitor = dynamic_cast<JassVisitor*>(visitor))
    return parserVisitor->visitFalseExpression(this);
  else
    return visitor->visitChildren(this);
}
JassParser::BaseExpressionContext* JassParser::baseExpression() {
  BaseExpressionContext *_localctx = _tracker.createInstance<BaseExpressionContext>(_ctx, getState());
  enterRule(_localctx, 24, JassParser::RuleBaseExpression);

#if __cplusplus > 201703L
  auto onExit = finally([=, this] {
#else
  auto onExit = finally([=] {
#endif
    exitRule();
  });
  try {
    setState(230);
    _errHandler->sync(this);
    switch (getInterpreter<atn::ParserATNSimulator>()->adaptivePredict(_input, 18, _ctx)) {
    case 1: {
      _localctx = _tracker.createInstance<JassParser::ReferenceExpressionContext>(_localctx);
      enterOuterAlt(_localctx, 1);
      setState(204);
      match(JassParser::ID);
      break;
    }

    case 2: {
      _localctx = _tracker.createInstance<JassParser::StringLiteralExpressionContext>(_localctx);
      enterOuterAlt(_localctx, 2);
      setState(205);
      match(JassParser::STRING_LITERAL);
      break;
    }

    case 3: {
      _localctx = _tracker.createInstance<JassParser::IntegerLiteralExpressionContext>(_localctx);
      enterOuterAlt(_localctx, 3);
      setState(206);
      match(JassParser::INTEGER);
      break;
    }

    case 4: {
      _localctx = _tracker.createInstance<JassParser::HexIntegerLiteralExpressionContext>(_localctx);
      enterOuterAlt(_localctx, 4);
      setState(207);
      match(JassParser::HEX_CONSTANT);
      break;
    }

    case 5: {
      _localctx = _tracker.createInstance<JassParser::DollarHexIntegerLiteralExpressionContext>(_localctx);
      enterOuterAlt(_localctx, 5);
      setState(208);
      match(JassParser::DOLLAR_HEX_CONSTANT);
      break;
    }

    case 6: {
      _localctx = _tracker.createInstance<JassParser::RawcodeLiteralExpressionContext>(_localctx);
      enterOuterAlt(_localctx, 6);
      setState(209);
      match(JassParser::RAWCODE);
      break;
    }

    case 7: {
      _localctx = _tracker.createInstance<JassParser::RealLiteralExpressionContext>(_localctx);
      enterOuterAlt(_localctx, 7);
      setState(210);
      match(JassParser::REAL);
      break;
    }

    case 8: {
      _localctx = _tracker.createInstance<JassParser::FunctionReferenceExpressionContext>(_localctx);
      enterOuterAlt(_localctx, 8);
      setState(211);
      match(JassParser::FUNCTION);
      setState(212);
      match(JassParser::ID);
      break;
    }

    case 9: {
      _localctx = _tracker.createInstance<JassParser::NullExpressionContext>(_localctx);
      enterOuterAlt(_localctx, 9);
      setState(213);
      match(JassParser::NULL_);
      break;
    }

    case 10: {
      _localctx = _tracker.createInstance<JassParser::TrueExpressionContext>(_localctx);
      enterOuterAlt(_localctx, 10);
      setState(214);
      match(JassParser::TRUE);
      break;
    }

    case 11: {
      _localctx = _tracker.createInstance<JassParser::FalseExpressionContext>(_localctx);
      enterOuterAlt(_localctx, 11);
      setState(215);
      match(JassParser::FALSE);
      break;
    }

    case 12: {
      _localctx = _tracker.createInstance<JassParser::ArrayReferenceExpressionContext>(_localctx);
      enterOuterAlt(_localctx, 12);
      setState(216);
      match(JassParser::ID);
      setState(217);
      match(JassParser::T__10);
      setState(218);
      expression();
      setState(219);
      match(JassParser::T__11);
      break;
    }

    case 13: {
      _localctx = _tracker.createInstance<JassParser::FunctionCallExpressionContext>(_localctx);
      enterOuterAlt(_localctx, 13);
      setState(221);
      functionExpression();
      break;
    }

    case 14: {
      _localctx = _tracker.createInstance<JassParser::ParentheticalExpressionContext>(_localctx);
      enterOuterAlt(_localctx, 14);
      setState(222);
      match(JassParser::T__12);
      setState(223);
      expression();
      setState(224);
      match(JassParser::T__13);
      break;
    }

    case 15: {
      _localctx = _tracker.createInstance<JassParser::NotExpressionContext>(_localctx);
      enterOuterAlt(_localctx, 15);
      setState(226);
      match(JassParser::NOT);
      setState(227);
      baseExpression();
      break;
    }

    case 16: {
      _localctx = _tracker.createInstance<JassParser::NegateExpressionContext>(_localctx);
      enterOuterAlt(_localctx, 16);
      setState(228);
      match(JassParser::T__3);
      setState(229);
      baseExpression();
      break;
    }

    default:
      break;
    }
   
  }
  catch (RecognitionException &e) {
    _errHandler->reportError(this, e);
    _localctx->exception = std::current_exception();
    _errHandler->recover(this, _localctx->exception);
  }

  return _localctx;
}

//----------------- ExpressionContext ------------------------------------------------------------------

JassParser::ExpressionContext::ExpressionContext(ParserRuleContext *parent, size_t invokingState)
  : ParserRuleContext(parent, invokingState) {
}

JassParser::BoolExpressionContext* JassParser::ExpressionContext::boolExpression() {
  return getRuleContext<JassParser::BoolExpressionContext>(0);
}


size_t JassParser::ExpressionContext::getRuleIndex() const {
  return JassParser::RuleExpression;
}

void JassParser::ExpressionContext::enterRule(tree::ParseTreeListener *listener) {
  auto parserListener = dynamic_cast<JassListener *>(listener);
  if (parserListener != nullptr)
    parserListener->enterExpression(this);
}

void JassParser::ExpressionContext::exitRule(tree::ParseTreeListener *listener) {
  auto parserListener = dynamic_cast<JassListener *>(listener);
  if (parserListener != nullptr)
    parserListener->exitExpression(this);
}


std::any JassParser::ExpressionContext::accept(tree::ParseTreeVisitor *visitor) {
  if (auto parserVisitor = dynamic_cast<JassVisitor*>(visitor))
    return parserVisitor->visitExpression(this);
  else
    return visitor->visitChildren(this);
}

JassParser::ExpressionContext* JassParser::expression() {
  ExpressionContext *_localctx = _tracker.createInstance<ExpressionContext>(_ctx, getState());
  enterRule(_localctx, 26, JassParser::RuleExpression);

#if __cplusplus > 201703L
  auto onExit = finally([=, this] {
#else
  auto onExit = finally([=] {
#endif
    exitRule();
  });
  try {
    enterOuterAlt(_localctx, 1);
    setState(232);
    boolExpression(0);
   
  }
  catch (RecognitionException &e) {
    _errHandler->reportError(this, e);
    _localctx->exception = std::current_exception();
    _errHandler->recover(this, _localctx->exception);
  }

  return _localctx;
}

//----------------- FunctionExpressionContext ------------------------------------------------------------------

JassParser::FunctionExpressionContext::FunctionExpressionContext(ParserRuleContext *parent, size_t invokingState)
  : ParserRuleContext(parent, invokingState) {
}

tree::TerminalNode* JassParser::FunctionExpressionContext::ID() {
  return getToken(JassParser::ID, 0);
}

JassParser::ArgsListContext* JassParser::FunctionExpressionContext::argsList() {
  return getRuleContext<JassParser::ArgsListContext>(0);
}


size_t JassParser::FunctionExpressionContext::getRuleIndex() const {
  return JassParser::RuleFunctionExpression;
}

void JassParser::FunctionExpressionContext::enterRule(tree::ParseTreeListener *listener) {
  auto parserListener = dynamic_cast<JassListener *>(listener);
  if (parserListener != nullptr)
    parserListener->enterFunctionExpression(this);
}

void JassParser::FunctionExpressionContext::exitRule(tree::ParseTreeListener *listener) {
  auto parserListener = dynamic_cast<JassListener *>(listener);
  if (parserListener != nullptr)
    parserListener->exitFunctionExpression(this);
}


std::any JassParser::FunctionExpressionContext::accept(tree::ParseTreeVisitor *visitor) {
  if (auto parserVisitor = dynamic_cast<JassVisitor*>(visitor))
    return parserVisitor->visitFunctionExpression(this);
  else
    return visitor->visitChildren(this);
}

JassParser::FunctionExpressionContext* JassParser::functionExpression() {
  FunctionExpressionContext *_localctx = _tracker.createInstance<FunctionExpressionContext>(_ctx, getState());
  enterRule(_localctx, 28, JassParser::RuleFunctionExpression);

#if __cplusplus > 201703L
  auto onExit = finally([=, this] {
#else
  auto onExit = finally([=] {
#endif
    exitRule();
  });
  try {
    setState(242);
    _errHandler->sync(this);
    switch (getInterpreter<atn::ParserATNSimulator>()->adaptivePredict(_input, 19, _ctx)) {
    case 1: {
      enterOuterAlt(_localctx, 1);
      setState(234);
      match(JassParser::ID);
      setState(235);
      match(JassParser::T__12);
      setState(236);
      argsList();
      setState(237);
      match(JassParser::T__13);
      break;
    }

    case 2: {
      enterOuterAlt(_localctx, 2);
      setState(239);
      match(JassParser::ID);
      setState(240);
      match(JassParser::T__12);
      setState(241);
      match(JassParser::T__13);
      break;
    }

    default:
      break;
    }
   
  }
  catch (RecognitionException &e) {
    _errHandler->reportError(this, e);
    _localctx->exception = std::current_exception();
    _errHandler->recover(this, _localctx->exception);
  }

  return _localctx;
}

//----------------- ArgsListContext ------------------------------------------------------------------

JassParser::ArgsListContext::ArgsListContext(ParserRuleContext *parent, size_t invokingState)
  : ParserRuleContext(parent, invokingState) {
}


size_t JassParser::ArgsListContext::getRuleIndex() const {
  return JassParser::RuleArgsList;
}

void JassParser::ArgsListContext::copyFrom(ArgsListContext *ctx) {
  ParserRuleContext::copyFrom(ctx);
}

//----------------- SingleArgumentContext ------------------------------------------------------------------

JassParser::ExpressionContext* JassParser::SingleArgumentContext::expression() {
  return getRuleContext<JassParser::ExpressionContext>(0);
}

JassParser::SingleArgumentContext::SingleArgumentContext(ArgsListContext *ctx) { copyFrom(ctx); }

void JassParser::SingleArgumentContext::enterRule(tree::ParseTreeListener *listener) {
  auto parserListener = dynamic_cast<JassListener *>(listener);
  if (parserListener != nullptr)
    parserListener->enterSingleArgument(this);
}
void JassParser::SingleArgumentContext::exitRule(tree::ParseTreeListener *listener) {
  auto parserListener = dynamic_cast<JassListener *>(listener);
  if (parserListener != nullptr)
    parserListener->exitSingleArgument(this);
}

std::any JassParser::SingleArgumentContext::accept(tree::ParseTreeVisitor *visitor) {
  if (auto parserVisitor = dynamic_cast<JassVisitor*>(visitor))
    return parserVisitor->visitSingleArgument(this);
  else
    return visitor->visitChildren(this);
}
//----------------- EmptyArgumentContext ------------------------------------------------------------------

JassParser::EmptyArgumentContext::EmptyArgumentContext(ArgsListContext *ctx) { copyFrom(ctx); }

void JassParser::EmptyArgumentContext::enterRule(tree::ParseTreeListener *listener) {
  auto parserListener = dynamic_cast<JassListener *>(listener);
  if (parserListener != nullptr)
    parserListener->enterEmptyArgument(this);
}
void JassParser::EmptyArgumentContext::exitRule(tree::ParseTreeListener *listener) {
  auto parserListener = dynamic_cast<JassListener *>(listener);
  if (parserListener != nullptr)
    parserListener->exitEmptyArgument(this);
}

std::any JassParser::EmptyArgumentContext::accept(tree::ParseTreeVisitor *visitor) {
  if (auto parserVisitor = dynamic_cast<JassVisitor*>(visitor))
    return parserVisitor->visitEmptyArgument(this);
  else
    return visitor->visitChildren(this);
}
//----------------- ListArgumentContext ------------------------------------------------------------------

JassParser::ExpressionContext* JassParser::ListArgumentContext::expression() {
  return getRuleContext<JassParser::ExpressionContext>(0);
}

JassParser::ArgsListContext* JassParser::ListArgumentContext::argsList() {
  return getRuleContext<JassParser::ArgsListContext>(0);
}

JassParser::ListArgumentContext::ListArgumentContext(ArgsListContext *ctx) { copyFrom(ctx); }

void JassParser::ListArgumentContext::enterRule(tree::ParseTreeListener *listener) {
  auto parserListener = dynamic_cast<JassListener *>(listener);
  if (parserListener != nullptr)
    parserListener->enterListArgument(this);
}
void JassParser::ListArgumentContext::exitRule(tree::ParseTreeListener *listener) {
  auto parserListener = dynamic_cast<JassListener *>(listener);
  if (parserListener != nullptr)
    parserListener->exitListArgument(this);
}

std::any JassParser::ListArgumentContext::accept(tree::ParseTreeVisitor *visitor) {
  if (auto parserVisitor = dynamic_cast<JassVisitor*>(visitor))
    return parserVisitor->visitListArgument(this);
  else
    return visitor->visitChildren(this);
}
JassParser::ArgsListContext* JassParser::argsList() {
  ArgsListContext *_localctx = _tracker.createInstance<ArgsListContext>(_ctx, getState());
  enterRule(_localctx, 30, JassParser::RuleArgsList);

#if __cplusplus > 201703L
  auto onExit = finally([=, this] {
#else
  auto onExit = finally([=] {
#endif
    exitRule();
  });
  try {
    setState(250);
    _errHandler->sync(this);
    switch (getInterpreter<atn::ParserATNSimulator>()->adaptivePredict(_input, 20, _ctx)) {
    case 1: {
      _localctx = _tracker.createInstance<JassParser::SingleArgumentContext>(_localctx);
      enterOuterAlt(_localctx, 1);
      setState(244);
      expression();
      break;
    }

    case 2: {
      _localctx = _tracker.createInstance<JassParser::ListArgumentContext>(_localctx);
      enterOuterAlt(_localctx, 2);
      setState(245);
      expression();
      setState(246);
      match(JassParser::T__14);
      setState(247);
      argsList();
      break;
    }

    case 3: {
      _localctx = _tracker.createInstance<JassParser::EmptyArgumentContext>(_localctx);
      enterOuterAlt(_localctx, 3);

      break;
    }

    default:
      break;
    }
   
  }
  catch (RecognitionException &e) {
    _errHandler->reportError(this, e);
    _localctx->exception = std::current_exception();
    _errHandler->recover(this, _localctx->exception);
  }

  return _localctx;
}

//----------------- StatementContext ------------------------------------------------------------------

JassParser::StatementContext::StatementContext(ParserRuleContext *parent, size_t invokingState)
  : ParserRuleContext(parent, invokingState) {
}


size_t JassParser::StatementContext::getRuleIndex() const {
  return JassParser::RuleStatement;
}

void JassParser::StatementContext::copyFrom(StatementContext *ctx) {
  ParserRuleContext::copyFrom(ctx);
}

//----------------- ArrayedAssignmentStatementContext ------------------------------------------------------------------

tree::TerminalNode* JassParser::ArrayedAssignmentStatementContext::SET() {
  return getToken(JassParser::SET, 0);
}

tree::TerminalNode* JassParser::ArrayedAssignmentStatementContext::ID() {
  return getToken(JassParser::ID, 0);
}

std::vector<JassParser::ExpressionContext *> JassParser::ArrayedAssignmentStatementContext::expression() {
  return getRuleContexts<JassParser::ExpressionContext>();
}

JassParser::ExpressionContext* JassParser::ArrayedAssignmentStatementContext::expression(size_t i) {
  return getRuleContext<JassParser::ExpressionContext>(i);
}

tree::TerminalNode* JassParser::ArrayedAssignmentStatementContext::EQUALS() {
  return getToken(JassParser::EQUALS, 0);
}

JassParser::NewlinesContext* JassParser::ArrayedAssignmentStatementContext::newlines() {
  return getRuleContext<JassParser::NewlinesContext>(0);
}

JassParser::ArrayedAssignmentStatementContext::ArrayedAssignmentStatementContext(StatementContext *ctx) { copyFrom(ctx); }

void JassParser::ArrayedAssignmentStatementContext::enterRule(tree::ParseTreeListener *listener) {
  auto parserListener = dynamic_cast<JassListener *>(listener);
  if (parserListener != nullptr)
    parserListener->enterArrayedAssignmentStatement(this);
}
void JassParser::ArrayedAssignmentStatementContext::exitRule(tree::ParseTreeListener *listener) {
  auto parserListener = dynamic_cast<JassListener *>(listener);
  if (parserListener != nullptr)
    parserListener->exitArrayedAssignmentStatement(this);
}

std::any JassParser::ArrayedAssignmentStatementContext::accept(tree::ParseTreeVisitor *visitor) {
  if (auto parserVisitor = dynamic_cast<JassVisitor*>(visitor))
    return parserVisitor->visitArrayedAssignmentStatement(this);
  else
    return visitor->visitChildren(this);
}
//----------------- IfStatementContext ------------------------------------------------------------------

tree::TerminalNode* JassParser::IfStatementContext::IF() {
  return getToken(JassParser::IF, 0);
}

JassParser::IfStatementPartialContext* JassParser::IfStatementContext::ifStatementPartial() {
  return getRuleContext<JassParser::IfStatementPartialContext>(0);
}

JassParser::IfStatementContext::IfStatementContext(StatementContext *ctx) { copyFrom(ctx); }

void JassParser::IfStatementContext::enterRule(tree::ParseTreeListener *listener) {
  auto parserListener = dynamic_cast<JassListener *>(listener);
  if (parserListener != nullptr)
    parserListener->enterIfStatement(this);
}
void JassParser::IfStatementContext::exitRule(tree::ParseTreeListener *listener) {
  auto parserListener = dynamic_cast<JassListener *>(listener);
  if (parserListener != nullptr)
    parserListener->exitIfStatement(this);
}

std::any JassParser::IfStatementContext::accept(tree::ParseTreeVisitor *visitor) {
  if (auto parserVisitor = dynamic_cast<JassVisitor*>(visitor))
    return parserVisitor->visitIfStatement(this);
  else
    return visitor->visitChildren(this);
}
//----------------- LocalStatementContext ------------------------------------------------------------------

JassParser::LocalContext* JassParser::LocalStatementContext::local() {
  return getRuleContext<JassParser::LocalContext>(0);
}

JassParser::LocalStatementContext::LocalStatementContext(StatementContext *ctx) { copyFrom(ctx); }

void JassParser::LocalStatementContext::enterRule(tree::ParseTreeListener *listener) {
  auto parserListener = dynamic_cast<JassListener *>(listener);
  if (parserListener != nullptr)
    parserListener->enterLocalStatement(this);
}
void JassParser::LocalStatementContext::exitRule(tree::ParseTreeListener *listener) {
  auto parserListener = dynamic_cast<JassListener *>(listener);
  if (parserListener != nullptr)
    parserListener->exitLocalStatement(this);
}

std::any JassParser::LocalStatementContext::accept(tree::ParseTreeVisitor *visitor) {
  if (auto parserVisitor = dynamic_cast<JassVisitor*>(visitor))
    return parserVisitor->visitLocalStatement(this);
  else
    return visitor->visitChildren(this);
}
//----------------- ReturnStatementContext ------------------------------------------------------------------

tree::TerminalNode* JassParser::ReturnStatementContext::RETURN() {
  return getToken(JassParser::RETURN, 0);
}

JassParser::ExpressionContext* JassParser::ReturnStatementContext::expression() {
  return getRuleContext<JassParser::ExpressionContext>(0);
}

JassParser::NewlinesContext* JassParser::ReturnStatementContext::newlines() {
  return getRuleContext<JassParser::NewlinesContext>(0);
}

JassParser::ReturnStatementContext::ReturnStatementContext(StatementContext *ctx) { copyFrom(ctx); }

void JassParser::ReturnStatementContext::enterRule(tree::ParseTreeListener *listener) {
  auto parserListener = dynamic_cast<JassListener *>(listener);
  if (parserListener != nullptr)
    parserListener->enterReturnStatement(this);
}
void JassParser::ReturnStatementContext::exitRule(tree::ParseTreeListener *listener) {
  auto parserListener = dynamic_cast<JassListener *>(listener);
  if (parserListener != nullptr)
    parserListener->exitReturnStatement(this);
}

std::any JassParser::ReturnStatementContext::accept(tree::ParseTreeVisitor *visitor) {
  if (auto parserVisitor = dynamic_cast<JassVisitor*>(visitor))
    return parserVisitor->visitReturnStatement(this);
  else
    return visitor->visitChildren(this);
}
//----------------- CallStatementContext ------------------------------------------------------------------

tree::TerminalNode* JassParser::CallStatementContext::CALL() {
  return getToken(JassParser::CALL, 0);
}

JassParser::FunctionExpressionContext* JassParser::CallStatementContext::functionExpression() {
  return getRuleContext<JassParser::FunctionExpressionContext>(0);
}

JassParser::NewlinesContext* JassParser::CallStatementContext::newlines() {
  return getRuleContext<JassParser::NewlinesContext>(0);
}

JassParser::CallStatementContext::CallStatementContext(StatementContext *ctx) { copyFrom(ctx); }

void JassParser::CallStatementContext::enterRule(tree::ParseTreeListener *listener) {
  auto parserListener = dynamic_cast<JassListener *>(listener);
  if (parserListener != nullptr)
    parserListener->enterCallStatement(this);
}
void JassParser::CallStatementContext::exitRule(tree::ParseTreeListener *listener) {
  auto parserListener = dynamic_cast<JassListener *>(listener);
  if (parserListener != nullptr)
    parserListener->exitCallStatement(this);
}

std::any JassParser::CallStatementContext::accept(tree::ParseTreeVisitor *visitor) {
  if (auto parserVisitor = dynamic_cast<JassVisitor*>(visitor))
    return parserVisitor->visitCallStatement(this);
  else
    return visitor->visitChildren(this);
}
//----------------- LoopStatementContext ------------------------------------------------------------------

tree::TerminalNode* JassParser::LoopStatementContext::LOOP() {
  return getToken(JassParser::LOOP, 0);
}

std::vector<JassParser::NewlinesContext *> JassParser::LoopStatementContext::newlines() {
  return getRuleContexts<JassParser::NewlinesContext>();
}

JassParser::NewlinesContext* JassParser::LoopStatementContext::newlines(size_t i) {
  return getRuleContext<JassParser::NewlinesContext>(i);
}

JassParser::StatementsContext* JassParser::LoopStatementContext::statements() {
  return getRuleContext<JassParser::StatementsContext>(0);
}

tree::TerminalNode* JassParser::LoopStatementContext::ENDLOOP() {
  return getToken(JassParser::ENDLOOP, 0);
}

JassParser::LoopStatementContext::LoopStatementContext(StatementContext *ctx) { copyFrom(ctx); }

void JassParser::LoopStatementContext::enterRule(tree::ParseTreeListener *listener) {
  auto parserListener = dynamic_cast<JassListener *>(listener);
  if (parserListener != nullptr)
    parserListener->enterLoopStatement(this);
}
void JassParser::LoopStatementContext::exitRule(tree::ParseTreeListener *listener) {
  auto parserListener = dynamic_cast<JassListener *>(listener);
  if (parserListener != nullptr)
    parserListener->exitLoopStatement(this);
}

std::any JassParser::LoopStatementContext::accept(tree::ParseTreeVisitor *visitor) {
  if (auto parserVisitor = dynamic_cast<JassVisitor*>(visitor))
    return parserVisitor->visitLoopStatement(this);
  else
    return visitor->visitChildren(this);
}
//----------------- DebugStatementContext ------------------------------------------------------------------

tree::TerminalNode* JassParser::DebugStatementContext::DEBUG() {
  return getToken(JassParser::DEBUG, 0);
}

JassParser::StatementContext* JassParser::DebugStatementContext::statement() {
  return getRuleContext<JassParser::StatementContext>(0);
}

JassParser::DebugStatementContext::DebugStatementContext(StatementContext *ctx) { copyFrom(ctx); }

void JassParser::DebugStatementContext::enterRule(tree::ParseTreeListener *listener) {
  auto parserListener = dynamic_cast<JassListener *>(listener);
  if (parserListener != nullptr)
    parserListener->enterDebugStatement(this);
}
void JassParser::DebugStatementContext::exitRule(tree::ParseTreeListener *listener) {
  auto parserListener = dynamic_cast<JassListener *>(listener);
  if (parserListener != nullptr)
    parserListener->exitDebugStatement(this);
}

std::any JassParser::DebugStatementContext::accept(tree::ParseTreeVisitor *visitor) {
  if (auto parserVisitor = dynamic_cast<JassVisitor*>(visitor))
    return parserVisitor->visitDebugStatement(this);
  else
    return visitor->visitChildren(this);
}
//----------------- ExitWhenStatementContext ------------------------------------------------------------------

tree::TerminalNode* JassParser::ExitWhenStatementContext::EXITWHEN() {
  return getToken(JassParser::EXITWHEN, 0);
}

JassParser::ExpressionContext* JassParser::ExitWhenStatementContext::expression() {
  return getRuleContext<JassParser::ExpressionContext>(0);
}

JassParser::NewlinesContext* JassParser::ExitWhenStatementContext::newlines() {
  return getRuleContext<JassParser::NewlinesContext>(0);
}

JassParser::ExitWhenStatementContext::ExitWhenStatementContext(StatementContext *ctx) { copyFrom(ctx); }

void JassParser::ExitWhenStatementContext::enterRule(tree::ParseTreeListener *listener) {
  auto parserListener = dynamic_cast<JassListener *>(listener);
  if (parserListener != nullptr)
    parserListener->enterExitWhenStatement(this);
}
void JassParser::ExitWhenStatementContext::exitRule(tree::ParseTreeListener *listener) {
  auto parserListener = dynamic_cast<JassListener *>(listener);
  if (parserListener != nullptr)
    parserListener->exitExitWhenStatement(this);
}

std::any JassParser::ExitWhenStatementContext::accept(tree::ParseTreeVisitor *visitor) {
  if (auto parserVisitor = dynamic_cast<JassVisitor*>(visitor))
    return parserVisitor->visitExitWhenStatement(this);
  else
    return visitor->visitChildren(this);
}
//----------------- SetStatementContext ------------------------------------------------------------------

tree::TerminalNode* JassParser::SetStatementContext::SET() {
  return getToken(JassParser::SET, 0);
}

tree::TerminalNode* JassParser::SetStatementContext::ID() {
  return getToken(JassParser::ID, 0);
}

tree::TerminalNode* JassParser::SetStatementContext::EQUALS() {
  return getToken(JassParser::EQUALS, 0);
}

JassParser::ExpressionContext* JassParser::SetStatementContext::expression() {
  return getRuleContext<JassParser::ExpressionContext>(0);
}

JassParser::NewlinesContext* JassParser::SetStatementContext::newlines() {
  return getRuleContext<JassParser::NewlinesContext>(0);
}

JassParser::SetStatementContext::SetStatementContext(StatementContext *ctx) { copyFrom(ctx); }

void JassParser::SetStatementContext::enterRule(tree::ParseTreeListener *listener) {
  auto parserListener = dynamic_cast<JassListener *>(listener);
  if (parserListener != nullptr)
    parserListener->enterSetStatement(this);
}
void JassParser::SetStatementContext::exitRule(tree::ParseTreeListener *listener) {
  auto parserListener = dynamic_cast<JassListener *>(listener);
  if (parserListener != nullptr)
    parserListener->exitSetStatement(this);
}

std::any JassParser::SetStatementContext::accept(tree::ParseTreeVisitor *visitor) {
  if (auto parserVisitor = dynamic_cast<JassVisitor*>(visitor))
    return parserVisitor->visitSetStatement(this);
  else
    return visitor->visitChildren(this);
}
//----------------- ReturnNothingStatementContext ------------------------------------------------------------------

tree::TerminalNode* JassParser::ReturnNothingStatementContext::RETURN() {
  return getToken(JassParser::RETURN, 0);
}

JassParser::NewlinesContext* JassParser::ReturnNothingStatementContext::newlines() {
  return getRuleContext<JassParser::NewlinesContext>(0);
}

JassParser::ReturnNothingStatementContext::ReturnNothingStatementContext(StatementContext *ctx) { copyFrom(ctx); }

void JassParser::ReturnNothingStatementContext::enterRule(tree::ParseTreeListener *listener) {
  auto parserListener = dynamic_cast<JassListener *>(listener);
  if (parserListener != nullptr)
    parserListener->enterReturnNothingStatement(this);
}
void JassParser::ReturnNothingStatementContext::exitRule(tree::ParseTreeListener *listener) {
  auto parserListener = dynamic_cast<JassListener *>(listener);
  if (parserListener != nullptr)
    parserListener->exitReturnNothingStatement(this);
}

std::any JassParser::ReturnNothingStatementContext::accept(tree::ParseTreeVisitor *visitor) {
  if (auto parserVisitor = dynamic_cast<JassVisitor*>(visitor))
    return parserVisitor->visitReturnNothingStatement(this);
  else
    return visitor->visitChildren(this);
}
JassParser::StatementContext* JassParser::statement() {
  StatementContext *_localctx = _tracker.createInstance<StatementContext>(_ctx, getState());
  enterRule(_localctx, 32, JassParser::RuleStatement);

#if __cplusplus > 201703L
  auto onExit = finally([=, this] {
#else
  auto onExit = finally([=] {
#endif
    exitRule();
  });
  try {
    setState(292);
    _errHandler->sync(this);
    switch (getInterpreter<atn::ParserATNSimulator>()->adaptivePredict(_input, 21, _ctx)) {
    case 1: {
      _localctx = _tracker.createInstance<JassParser::CallStatementContext>(_localctx);
      enterOuterAlt(_localctx, 1);
      setState(252);
      match(JassParser::CALL);
      setState(253);
      functionExpression();
      setState(254);
      newlines();
      break;
    }

    case 2: {
      _localctx = _tracker.createInstance<JassParser::SetStatementContext>(_localctx);
      enterOuterAlt(_localctx, 2);
      setState(256);
      match(JassParser::SET);
      setState(257);
      match(JassParser::ID);
      setState(258);
      match(JassParser::EQUALS);
      setState(259);
      expression();
      setState(260);
      newlines();
      break;
    }

    case 3: {
      _localctx = _tracker.createInstance<JassParser::ArrayedAssignmentStatementContext>(_localctx);
      enterOuterAlt(_localctx, 3);
      setState(262);
      match(JassParser::SET);
      setState(263);
      match(JassParser::ID);
      setState(264);
      match(JassParser::T__10);
      setState(265);
      expression();
      setState(266);
      match(JassParser::T__11);
      setState(267);
      match(JassParser::EQUALS);
      setState(268);
      expression();
      setState(269);
      newlines();
      break;
    }

    case 4: {
      _localctx = _tracker.createInstance<JassParser::ReturnStatementContext>(_localctx);
      enterOuterAlt(_localctx, 4);
      setState(271);
      match(JassParser::RETURN);
      setState(272);
      expression();
      setState(273);
      newlines();
      break;
    }

    case 5: {
      _localctx = _tracker.createInstance<JassParser::ReturnNothingStatementContext>(_localctx);
      enterOuterAlt(_localctx, 5);
      setState(275);
      match(JassParser::RETURN);
      setState(276);
      newlines();
      break;
    }

    case 6: {
      _localctx = _tracker.createInstance<JassParser::ExitWhenStatementContext>(_localctx);
      enterOuterAlt(_localctx, 6);
      setState(277);
      match(JassParser::EXITWHEN);
      setState(278);
      expression();
      setState(279);
      newlines();
      break;
    }

    case 7: {
      _localctx = _tracker.createInstance<JassParser::LocalStatementContext>(_localctx);
      enterOuterAlt(_localctx, 7);
      setState(281);
      local();
      break;
    }

    case 8: {
      _localctx = _tracker.createInstance<JassParser::LoopStatementContext>(_localctx);
      enterOuterAlt(_localctx, 8);
      setState(282);
      match(JassParser::LOOP);
      setState(283);
      newlines();
      setState(284);
      statements();
      setState(285);
      match(JassParser::ENDLOOP);
      setState(286);
      newlines();
      break;
    }

    case 9: {
      _localctx = _tracker.createInstance<JassParser::IfStatementContext>(_localctx);
      enterOuterAlt(_localctx, 9);
      setState(288);
      match(JassParser::IF);
      setState(289);
      ifStatementPartial();
      break;
    }

    case 10: {
      _localctx = _tracker.createInstance<JassParser::DebugStatementContext>(_localctx);
      enterOuterAlt(_localctx, 10);
      setState(290);
      match(JassParser::DEBUG);
      setState(291);
      statement();
      break;
    }

    default:
      break;
    }
   
  }
  catch (RecognitionException &e) {
    _errHandler->reportError(this, e);
    _localctx->exception = std::current_exception();
    _errHandler->recover(this, _localctx->exception);
  }

  return _localctx;
}

//----------------- IfStatementPartialContext ------------------------------------------------------------------

JassParser::IfStatementPartialContext::IfStatementPartialContext(ParserRuleContext *parent, size_t invokingState)
  : ParserRuleContext(parent, invokingState) {
}


size_t JassParser::IfStatementPartialContext::getRuleIndex() const {
  return JassParser::RuleIfStatementPartial;
}

void JassParser::IfStatementPartialContext::copyFrom(IfStatementPartialContext *ctx) {
  ParserRuleContext::copyFrom(ctx);
}

//----------------- IfElseIfStatementContext ------------------------------------------------------------------

JassParser::ExpressionContext* JassParser::IfElseIfStatementContext::expression() {
  return getRuleContext<JassParser::ExpressionContext>(0);
}

tree::TerminalNode* JassParser::IfElseIfStatementContext::THEN() {
  return getToken(JassParser::THEN, 0);
}

JassParser::NewlinesContext* JassParser::IfElseIfStatementContext::newlines() {
  return getRuleContext<JassParser::NewlinesContext>(0);
}

JassParser::StatementsContext* JassParser::IfElseIfStatementContext::statements() {
  return getRuleContext<JassParser::StatementsContext>(0);
}

tree::TerminalNode* JassParser::IfElseIfStatementContext::ELSEIF() {
  return getToken(JassParser::ELSEIF, 0);
}

JassParser::IfStatementPartialContext* JassParser::IfElseIfStatementContext::ifStatementPartial() {
  return getRuleContext<JassParser::IfStatementPartialContext>(0);
}

JassParser::IfElseIfStatementContext::IfElseIfStatementContext(IfStatementPartialContext *ctx) { copyFrom(ctx); }

void JassParser::IfElseIfStatementContext::enterRule(tree::ParseTreeListener *listener) {
  auto parserListener = dynamic_cast<JassListener *>(listener);
  if (parserListener != nullptr)
    parserListener->enterIfElseIfStatement(this);
}
void JassParser::IfElseIfStatementContext::exitRule(tree::ParseTreeListener *listener) {
  auto parserListener = dynamic_cast<JassListener *>(listener);
  if (parserListener != nullptr)
    parserListener->exitIfElseIfStatement(this);
}

std::any JassParser::IfElseIfStatementContext::accept(tree::ParseTreeVisitor *visitor) {
  if (auto parserVisitor = dynamic_cast<JassVisitor*>(visitor))
    return parserVisitor->visitIfElseIfStatement(this);
  else
    return visitor->visitChildren(this);
}
//----------------- IfElseStatementContext ------------------------------------------------------------------

JassParser::ExpressionContext* JassParser::IfElseStatementContext::expression() {
  return getRuleContext<JassParser::ExpressionContext>(0);
}

tree::TerminalNode* JassParser::IfElseStatementContext::THEN() {
  return getToken(JassParser::THEN, 0);
}

std::vector<JassParser::NewlinesContext *> JassParser::IfElseStatementContext::newlines() {
  return getRuleContexts<JassParser::NewlinesContext>();
}

JassParser::NewlinesContext* JassParser::IfElseStatementContext::newlines(size_t i) {
  return getRuleContext<JassParser::NewlinesContext>(i);
}

std::vector<JassParser::StatementsContext *> JassParser::IfElseStatementContext::statements() {
  return getRuleContexts<JassParser::StatementsContext>();
}

JassParser::StatementsContext* JassParser::IfElseStatementContext::statements(size_t i) {
  return getRuleContext<JassParser::StatementsContext>(i);
}

tree::TerminalNode* JassParser::IfElseStatementContext::ELSE() {
  return getToken(JassParser::ELSE, 0);
}

tree::TerminalNode* JassParser::IfElseStatementContext::ENDIF() {
  return getToken(JassParser::ENDIF, 0);
}

JassParser::IfElseStatementContext::IfElseStatementContext(IfStatementPartialContext *ctx) { copyFrom(ctx); }

void JassParser::IfElseStatementContext::enterRule(tree::ParseTreeListener *listener) {
  auto parserListener = dynamic_cast<JassListener *>(listener);
  if (parserListener != nullptr)
    parserListener->enterIfElseStatement(this);
}
void JassParser::IfElseStatementContext::exitRule(tree::ParseTreeListener *listener) {
  auto parserListener = dynamic_cast<JassListener *>(listener);
  if (parserListener != nullptr)
    parserListener->exitIfElseStatement(this);
}

std::any JassParser::IfElseStatementContext::accept(tree::ParseTreeVisitor *visitor) {
  if (auto parserVisitor = dynamic_cast<JassVisitor*>(visitor))
    return parserVisitor->visitIfElseStatement(this);
  else
    return visitor->visitChildren(this);
}
//----------------- SimpleIfStatementContext ------------------------------------------------------------------

JassParser::ExpressionContext* JassParser::SimpleIfStatementContext::expression() {
  return getRuleContext<JassParser::ExpressionContext>(0);
}

tree::TerminalNode* JassParser::SimpleIfStatementContext::THEN() {
  return getToken(JassParser::THEN, 0);
}

std::vector<JassParser::NewlinesContext *> JassParser::SimpleIfStatementContext::newlines() {
  return getRuleContexts<JassParser::NewlinesContext>();
}

JassParser::NewlinesContext* JassParser::SimpleIfStatementContext::newlines(size_t i) {
  return getRuleContext<JassParser::NewlinesContext>(i);
}

JassParser::StatementsContext* JassParser::SimpleIfStatementContext::statements() {
  return getRuleContext<JassParser::StatementsContext>(0);
}

tree::TerminalNode* JassParser::SimpleIfStatementContext::ENDIF() {
  return getToken(JassParser::ENDIF, 0);
}

JassParser::SimpleIfStatementContext::SimpleIfStatementContext(IfStatementPartialContext *ctx) { copyFrom(ctx); }

void JassParser::SimpleIfStatementContext::enterRule(tree::ParseTreeListener *listener) {
  auto parserListener = dynamic_cast<JassListener *>(listener);
  if (parserListener != nullptr)
    parserListener->enterSimpleIfStatement(this);
}
void JassParser::SimpleIfStatementContext::exitRule(tree::ParseTreeListener *listener) {
  auto parserListener = dynamic_cast<JassListener *>(listener);
  if (parserListener != nullptr)
    parserListener->exitSimpleIfStatement(this);
}

std::any JassParser::SimpleIfStatementContext::accept(tree::ParseTreeVisitor *visitor) {
  if (auto parserVisitor = dynamic_cast<JassVisitor*>(visitor))
    return parserVisitor->visitSimpleIfStatement(this);
  else
    return visitor->visitChildren(this);
}
JassParser::IfStatementPartialContext* JassParser::ifStatementPartial() {
  IfStatementPartialContext *_localctx = _tracker.createInstance<IfStatementPartialContext>(_ctx, getState());
  enterRule(_localctx, 34, JassParser::RuleIfStatementPartial);

#if __cplusplus > 201703L
  auto onExit = finally([=, this] {
#else
  auto onExit = finally([=] {
#endif
    exitRule();
  });
  try {
    setState(318);
    _errHandler->sync(this);
    switch (getInterpreter<atn::ParserATNSimulator>()->adaptivePredict(_input, 22, _ctx)) {
    case 1: {
      _localctx = _tracker.createInstance<JassParser::SimpleIfStatementContext>(_localctx);
      enterOuterAlt(_localctx, 1);
      setState(294);
      expression();
      setState(295);
      match(JassParser::THEN);
      setState(296);
      newlines();
      setState(297);
      statements();
      setState(298);
      match(JassParser::ENDIF);
      setState(299);
      newlines();
      break;
    }

    case 2: {
      _localctx = _tracker.createInstance<JassParser::IfElseStatementContext>(_localctx);
      enterOuterAlt(_localctx, 2);
      setState(301);
      expression();
      setState(302);
      match(JassParser::THEN);
      setState(303);
      newlines();
      setState(304);
      statements();
      setState(305);
      match(JassParser::ELSE);
      setState(306);
      newlines();
      setState(307);
      statements();
      setState(308);
      match(JassParser::ENDIF);
      setState(309);
      newlines();
      break;
    }

    case 3: {
      _localctx = _tracker.createInstance<JassParser::IfElseIfStatementContext>(_localctx);
      enterOuterAlt(_localctx, 3);
      setState(311);
      expression();
      setState(312);
      match(JassParser::THEN);
      setState(313);
      newlines();
      setState(314);
      statements();
      setState(315);
      match(JassParser::ELSEIF);
      setState(316);
      ifStatementPartial();
      break;
    }

    default:
      break;
    }
   
  }
  catch (RecognitionException &e) {
    _errHandler->reportError(this, e);
    _localctx->exception = std::current_exception();
    _errHandler->recover(this, _localctx->exception);
  }

  return _localctx;
}

//----------------- ParamContext ------------------------------------------------------------------

JassParser::ParamContext::ParamContext(ParserRuleContext *parent, size_t invokingState)
  : ParserRuleContext(parent, invokingState) {
}

JassParser::TypeContext* JassParser::ParamContext::type() {
  return getRuleContext<JassParser::TypeContext>(0);
}

tree::TerminalNode* JassParser::ParamContext::ID() {
  return getToken(JassParser::ID, 0);
}


size_t JassParser::ParamContext::getRuleIndex() const {
  return JassParser::RuleParam;
}

void JassParser::ParamContext::enterRule(tree::ParseTreeListener *listener) {
  auto parserListener = dynamic_cast<JassListener *>(listener);
  if (parserListener != nullptr)
    parserListener->enterParam(this);
}

void JassParser::ParamContext::exitRule(tree::ParseTreeListener *listener) {
  auto parserListener = dynamic_cast<JassListener *>(listener);
  if (parserListener != nullptr)
    parserListener->exitParam(this);
}


std::any JassParser::ParamContext::accept(tree::ParseTreeVisitor *visitor) {
  if (auto parserVisitor = dynamic_cast<JassVisitor*>(visitor))
    return parserVisitor->visitParam(this);
  else
    return visitor->visitChildren(this);
}

JassParser::ParamContext* JassParser::param() {
  ParamContext *_localctx = _tracker.createInstance<ParamContext>(_ctx, getState());
  enterRule(_localctx, 36, JassParser::RuleParam);

#if __cplusplus > 201703L
  auto onExit = finally([=, this] {
#else
  auto onExit = finally([=] {
#endif
    exitRule();
  });
  try {
    enterOuterAlt(_localctx, 1);
    setState(320);
    type();
    setState(321);
    match(JassParser::ID);
   
  }
  catch (RecognitionException &e) {
    _errHandler->reportError(this, e);
    _localctx->exception = std::current_exception();
    _errHandler->recover(this, _localctx->exception);
  }

  return _localctx;
}

//----------------- ParamListContext ------------------------------------------------------------------

JassParser::ParamListContext::ParamListContext(ParserRuleContext *parent, size_t invokingState)
  : ParserRuleContext(parent, invokingState) {
}


size_t JassParser::ParamListContext::getRuleIndex() const {
  return JassParser::RuleParamList;
}

void JassParser::ParamListContext::copyFrom(ParamListContext *ctx) {
  ParserRuleContext::copyFrom(ctx);
}

//----------------- NothingParameterContext ------------------------------------------------------------------

tree::TerminalNode* JassParser::NothingParameterContext::NOTHING() {
  return getToken(JassParser::NOTHING, 0);
}

JassParser::NothingParameterContext::NothingParameterContext(ParamListContext *ctx) { copyFrom(ctx); }

void JassParser::NothingParameterContext::enterRule(tree::ParseTreeListener *listener) {
  auto parserListener = dynamic_cast<JassListener *>(listener);
  if (parserListener != nullptr)
    parserListener->enterNothingParameter(this);
}
void JassParser::NothingParameterContext::exitRule(tree::ParseTreeListener *listener) {
  auto parserListener = dynamic_cast<JassListener *>(listener);
  if (parserListener != nullptr)
    parserListener->exitNothingParameter(this);
}

std::any JassParser::NothingParameterContext::accept(tree::ParseTreeVisitor *visitor) {
  if (auto parserVisitor = dynamic_cast<JassVisitor*>(visitor))
    return parserVisitor->visitNothingParameter(this);
  else
    return visitor->visitChildren(this);
}
//----------------- SingleParameterContext ------------------------------------------------------------------

JassParser::ParamContext* JassParser::SingleParameterContext::param() {
  return getRuleContext<JassParser::ParamContext>(0);
}

JassParser::SingleParameterContext::SingleParameterContext(ParamListContext *ctx) { copyFrom(ctx); }

void JassParser::SingleParameterContext::enterRule(tree::ParseTreeListener *listener) {
  auto parserListener = dynamic_cast<JassListener *>(listener);
  if (parserListener != nullptr)
    parserListener->enterSingleParameter(this);
}
void JassParser::SingleParameterContext::exitRule(tree::ParseTreeListener *listener) {
  auto parserListener = dynamic_cast<JassListener *>(listener);
  if (parserListener != nullptr)
    parserListener->exitSingleParameter(this);
}

std::any JassParser::SingleParameterContext::accept(tree::ParseTreeVisitor *visitor) {
  if (auto parserVisitor = dynamic_cast<JassVisitor*>(visitor))
    return parserVisitor->visitSingleParameter(this);
  else
    return visitor->visitChildren(this);
}
//----------------- ListParameterContext ------------------------------------------------------------------

JassParser::ParamContext* JassParser::ListParameterContext::param() {
  return getRuleContext<JassParser::ParamContext>(0);
}

JassParser::ParamListContext* JassParser::ListParameterContext::paramList() {
  return getRuleContext<JassParser::ParamListContext>(0);
}

JassParser::ListParameterContext::ListParameterContext(ParamListContext *ctx) { copyFrom(ctx); }

void JassParser::ListParameterContext::enterRule(tree::ParseTreeListener *listener) {
  auto parserListener = dynamic_cast<JassListener *>(listener);
  if (parserListener != nullptr)
    parserListener->enterListParameter(this);
}
void JassParser::ListParameterContext::exitRule(tree::ParseTreeListener *listener) {
  auto parserListener = dynamic_cast<JassListener *>(listener);
  if (parserListener != nullptr)
    parserListener->exitListParameter(this);
}

std::any JassParser::ListParameterContext::accept(tree::ParseTreeVisitor *visitor) {
  if (auto parserVisitor = dynamic_cast<JassVisitor*>(visitor))
    return parserVisitor->visitListParameter(this);
  else
    return visitor->visitChildren(this);
}
JassParser::ParamListContext* JassParser::paramList() {
  ParamListContext *_localctx = _tracker.createInstance<ParamListContext>(_ctx, getState());
  enterRule(_localctx, 38, JassParser::RuleParamList);

#if __cplusplus > 201703L
  auto onExit = finally([=, this] {
#else
  auto onExit = finally([=] {
#endif
    exitRule();
  });
  try {
    setState(329);
    _errHandler->sync(this);
    switch (getInterpreter<atn::ParserATNSimulator>()->adaptivePredict(_input, 23, _ctx)) {
    case 1: {
      _localctx = _tracker.createInstance<JassParser::SingleParameterContext>(_localctx);
      enterOuterAlt(_localctx, 1);
      setState(323);
      param();
      break;
    }

    case 2: {
      _localctx = _tracker.createInstance<JassParser::ListParameterContext>(_localctx);
      enterOuterAlt(_localctx, 2);
      setState(324);
      param();
      setState(325);
      match(JassParser::T__14);
      setState(326);
      paramList();
      break;
    }

    case 3: {
      _localctx = _tracker.createInstance<JassParser::NothingParameterContext>(_localctx);
      enterOuterAlt(_localctx, 3);
      setState(328);
      match(JassParser::NOTHING);
      break;
    }

    default:
      break;
    }
   
  }
  catch (RecognitionException &e) {
    _errHandler->reportError(this, e);
    _localctx->exception = std::current_exception();
    _errHandler->recover(this, _localctx->exception);
  }

  return _localctx;
}

//----------------- GlobalsBlockContext ------------------------------------------------------------------

JassParser::GlobalsBlockContext::GlobalsBlockContext(ParserRuleContext *parent, size_t invokingState)
  : ParserRuleContext(parent, invokingState) {
}

tree::TerminalNode* JassParser::GlobalsBlockContext::GLOBALS() {
  return getToken(JassParser::GLOBALS, 0);
}

std::vector<JassParser::NewlinesContext *> JassParser::GlobalsBlockContext::newlines() {
  return getRuleContexts<JassParser::NewlinesContext>();
}

JassParser::NewlinesContext* JassParser::GlobalsBlockContext::newlines(size_t i) {
  return getRuleContext<JassParser::NewlinesContext>(i);
}

tree::TerminalNode* JassParser::GlobalsBlockContext::ENDGLOBALS() {
  return getToken(JassParser::ENDGLOBALS, 0);
}

std::vector<JassParser::GlobalContext *> JassParser::GlobalsBlockContext::global() {
  return getRuleContexts<JassParser::GlobalContext>();
}

JassParser::GlobalContext* JassParser::GlobalsBlockContext::global(size_t i) {
  return getRuleContext<JassParser::GlobalContext>(i);
}


size_t JassParser::GlobalsBlockContext::getRuleIndex() const {
  return JassParser::RuleGlobalsBlock;
}

void JassParser::GlobalsBlockContext::enterRule(tree::ParseTreeListener *listener) {
  auto parserListener = dynamic_cast<JassListener *>(listener);
  if (parserListener != nullptr)
    parserListener->enterGlobalsBlock(this);
}

void JassParser::GlobalsBlockContext::exitRule(tree::ParseTreeListener *listener) {
  auto parserListener = dynamic_cast<JassListener *>(listener);
  if (parserListener != nullptr)
    parserListener->exitGlobalsBlock(this);
}


std::any JassParser::GlobalsBlockContext::accept(tree::ParseTreeVisitor *visitor) {
  if (auto parserVisitor = dynamic_cast<JassVisitor*>(visitor))
    return parserVisitor->visitGlobalsBlock(this);
  else
    return visitor->visitChildren(this);
}

JassParser::GlobalsBlockContext* JassParser::globalsBlock() {
  GlobalsBlockContext *_localctx = _tracker.createInstance<GlobalsBlockContext>(_ctx, getState());
  enterRule(_localctx, 40, JassParser::RuleGlobalsBlock);
  size_t _la = 0;

#if __cplusplus > 201703L
  auto onExit = finally([=, this] {
#else
  auto onExit = finally([=] {
#endif
    exitRule();
  });
  try {
    enterOuterAlt(_localctx, 1);
    setState(331);
    match(JassParser::GLOBALS);
    setState(332);
    newlines();
    setState(336);
    _errHandler->sync(this);
    _la = _input->LA(1);
    while ((((_la & ~ 0x3fULL) == 0) &&
      ((1ULL << _la) & 18014467245735936) != 0)) {
      setState(333);
      global();
      setState(338);
      _errHandler->sync(this);
      _la = _input->LA(1);
    }
    setState(339);
    match(JassParser::ENDGLOBALS);
    setState(340);
    newlines();
   
  }
  catch (RecognitionException &e) {
    _errHandler->reportError(this, e);
    _localctx->exception = std::current_exception();
    _errHandler->recover(this, _localctx->exception);
  }

  return _localctx;
}

//----------------- TypeDeclarationBlockContext ------------------------------------------------------------------

JassParser::TypeDeclarationBlockContext::TypeDeclarationBlockContext(ParserRuleContext *parent, size_t invokingState)
  : ParserRuleContext(parent, invokingState) {
}

std::vector<JassParser::TypeDeclarationContext *> JassParser::TypeDeclarationBlockContext::typeDeclaration() {
  return getRuleContexts<JassParser::TypeDeclarationContext>();
}

JassParser::TypeDeclarationContext* JassParser::TypeDeclarationBlockContext::typeDeclaration(size_t i) {
  return getRuleContext<JassParser::TypeDeclarationContext>(i);
}


size_t JassParser::TypeDeclarationBlockContext::getRuleIndex() const {
  return JassParser::RuleTypeDeclarationBlock;
}

void JassParser::TypeDeclarationBlockContext::enterRule(tree::ParseTreeListener *listener) {
  auto parserListener = dynamic_cast<JassListener *>(listener);
  if (parserListener != nullptr)
    parserListener->enterTypeDeclarationBlock(this);
}

void JassParser::TypeDeclarationBlockContext::exitRule(tree::ParseTreeListener *listener) {
  auto parserListener = dynamic_cast<JassListener *>(listener);
  if (parserListener != nullptr)
    parserListener->exitTypeDeclarationBlock(this);
}


std::any JassParser::TypeDeclarationBlockContext::accept(tree::ParseTreeVisitor *visitor) {
  if (auto parserVisitor = dynamic_cast<JassVisitor*>(visitor))
    return parserVisitor->visitTypeDeclarationBlock(this);
  else
    return visitor->visitChildren(this);
}

JassParser::TypeDeclarationBlockContext* JassParser::typeDeclarationBlock() {
  TypeDeclarationBlockContext *_localctx = _tracker.createInstance<TypeDeclarationBlockContext>(_ctx, getState());
  enterRule(_localctx, 42, JassParser::RuleTypeDeclarationBlock);
  size_t _la = 0;

#if __cplusplus > 201703L
  auto onExit = finally([=, this] {
#else
  auto onExit = finally([=] {
#endif
    exitRule();
  });
  try {
    enterOuterAlt(_localctx, 1);
    setState(345);
    _errHandler->sync(this);
    _la = _input->LA(1);
    while (_la == JassParser::TYPE) {
      setState(342);
      typeDeclaration();
      setState(347);
      _errHandler->sync(this);
      _la = _input->LA(1);
    }
   
  }
  catch (RecognitionException &e) {
    _errHandler->reportError(this, e);
    _localctx->exception = std::current_exception();
    _errHandler->recover(this, _localctx->exception);
  }

  return _localctx;
}

//----------------- NativeBlockContext ------------------------------------------------------------------

JassParser::NativeBlockContext::NativeBlockContext(ParserRuleContext *parent, size_t invokingState)
  : ParserRuleContext(parent, invokingState) {
}

tree::TerminalNode* JassParser::NativeBlockContext::NATIVE() {
  return getToken(JassParser::NATIVE, 0);
}

tree::TerminalNode* JassParser::NativeBlockContext::ID() {
  return getToken(JassParser::ID, 0);
}

tree::TerminalNode* JassParser::NativeBlockContext::TAKES() {
  return getToken(JassParser::TAKES, 0);
}

JassParser::ParamListContext* JassParser::NativeBlockContext::paramList() {
  return getRuleContext<JassParser::ParamListContext>(0);
}

tree::TerminalNode* JassParser::NativeBlockContext::RETURNS() {
  return getToken(JassParser::RETURNS, 0);
}

JassParser::TypeContext* JassParser::NativeBlockContext::type() {
  return getRuleContext<JassParser::TypeContext>(0);
}

JassParser::NewlinesContext* JassParser::NativeBlockContext::newlines() {
  return getRuleContext<JassParser::NewlinesContext>(0);
}

tree::TerminalNode* JassParser::NativeBlockContext::CONSTANT() {
  return getToken(JassParser::CONSTANT, 0);
}


size_t JassParser::NativeBlockContext::getRuleIndex() const {
  return JassParser::RuleNativeBlock;
}

void JassParser::NativeBlockContext::enterRule(tree::ParseTreeListener *listener) {
  auto parserListener = dynamic_cast<JassListener *>(listener);
  if (parserListener != nullptr)
    parserListener->enterNativeBlock(this);
}

void JassParser::NativeBlockContext::exitRule(tree::ParseTreeListener *listener) {
  auto parserListener = dynamic_cast<JassListener *>(listener);
  if (parserListener != nullptr)
    parserListener->exitNativeBlock(this);
}


std::any JassParser::NativeBlockContext::accept(tree::ParseTreeVisitor *visitor) {
  if (auto parserVisitor = dynamic_cast<JassVisitor*>(visitor))
    return parserVisitor->visitNativeBlock(this);
  else
    return visitor->visitChildren(this);
}

JassParser::NativeBlockContext* JassParser::nativeBlock() {
  NativeBlockContext *_localctx = _tracker.createInstance<NativeBlockContext>(_ctx, getState());
  enterRule(_localctx, 44, JassParser::RuleNativeBlock);
  size_t _la = 0;

#if __cplusplus > 201703L
  auto onExit = finally([=, this] {
#else
  auto onExit = finally([=] {
#endif
    exitRule();
  });
  try {
    enterOuterAlt(_localctx, 1);
    setState(349);
    _errHandler->sync(this);

    _la = _input->LA(1);
    if (_la == JassParser::CONSTANT) {
      setState(348);
      match(JassParser::CONSTANT);
    }
    setState(351);
    match(JassParser::NATIVE);
    setState(352);
    match(JassParser::ID);
    setState(353);
    match(JassParser::TAKES);
    setState(354);
    paramList();
    setState(355);
    match(JassParser::RETURNS);
    setState(356);
    type();
    setState(357);
    newlines();
   
  }
  catch (RecognitionException &e) {
    _errHandler->reportError(this, e);
    _localctx->exception = std::current_exception();
    _errHandler->recover(this, _localctx->exception);
  }

  return _localctx;
}

//----------------- BlockContext ------------------------------------------------------------------

JassParser::BlockContext::BlockContext(ParserRuleContext *parent, size_t invokingState)
  : ParserRuleContext(parent, invokingState) {
}

JassParser::GlobalsBlockContext* JassParser::BlockContext::globalsBlock() {
  return getRuleContext<JassParser::GlobalsBlockContext>(0);
}

JassParser::NativeBlockContext* JassParser::BlockContext::nativeBlock() {
  return getRuleContext<JassParser::NativeBlockContext>(0);
}


size_t JassParser::BlockContext::getRuleIndex() const {
  return JassParser::RuleBlock;
}

void JassParser::BlockContext::enterRule(tree::ParseTreeListener *listener) {
  auto parserListener = dynamic_cast<JassListener *>(listener);
  if (parserListener != nullptr)
    parserListener->enterBlock(this);
}

void JassParser::BlockContext::exitRule(tree::ParseTreeListener *listener) {
  auto parserListener = dynamic_cast<JassListener *>(listener);
  if (parserListener != nullptr)
    parserListener->exitBlock(this);
}


std::any JassParser::BlockContext::accept(tree::ParseTreeVisitor *visitor) {
  if (auto parserVisitor = dynamic_cast<JassVisitor*>(visitor))
    return parserVisitor->visitBlock(this);
  else
    return visitor->visitChildren(this);
}

JassParser::BlockContext* JassParser::block() {
  BlockContext *_localctx = _tracker.createInstance<BlockContext>(_ctx, getState());
  enterRule(_localctx, 46, JassParser::RuleBlock);

#if __cplusplus > 201703L
  auto onExit = finally([=, this] {
#else
  auto onExit = finally([=] {
#endif
    exitRule();
  });
  try {
    setState(361);
    _errHandler->sync(this);
    switch (_input->LA(1)) {
      case JassParser::GLOBALS: {
        enterOuterAlt(_localctx, 1);
        setState(359);
        globalsBlock();
        break;
      }

      case JassParser::NATIVE:
      case JassParser::CONSTANT: {
        enterOuterAlt(_localctx, 2);
        setState(360);
        nativeBlock();
        break;
      }

    default:
      throw NoViableAltException(this);
    }
   
  }
  catch (RecognitionException &e) {
    _errHandler->reportError(this, e);
    _localctx->exception = std::current_exception();
    _errHandler->recover(this, _localctx->exception);
  }

  return _localctx;
}

//----------------- FunctionBlockContext ------------------------------------------------------------------

JassParser::FunctionBlockContext::FunctionBlockContext(ParserRuleContext *parent, size_t invokingState)
  : ParserRuleContext(parent, invokingState) {
}

tree::TerminalNode* JassParser::FunctionBlockContext::FUNCTION() {
  return getToken(JassParser::FUNCTION, 0);
}

tree::TerminalNode* JassParser::FunctionBlockContext::ID() {
  return getToken(JassParser::ID, 0);
}

tree::TerminalNode* JassParser::FunctionBlockContext::TAKES() {
  return getToken(JassParser::TAKES, 0);
}

JassParser::ParamListContext* JassParser::FunctionBlockContext::paramList() {
  return getRuleContext<JassParser::ParamListContext>(0);
}

tree::TerminalNode* JassParser::FunctionBlockContext::RETURNS() {
  return getToken(JassParser::RETURNS, 0);
}

JassParser::TypeContext* JassParser::FunctionBlockContext::type() {
  return getRuleContext<JassParser::TypeContext>(0);
}

std::vector<JassParser::NewlinesContext *> JassParser::FunctionBlockContext::newlines() {
  return getRuleContexts<JassParser::NewlinesContext>();
}

JassParser::NewlinesContext* JassParser::FunctionBlockContext::newlines(size_t i) {
  return getRuleContext<JassParser::NewlinesContext>(i);
}

JassParser::StatementsContext* JassParser::FunctionBlockContext::statements() {
  return getRuleContext<JassParser::StatementsContext>(0);
}

tree::TerminalNode* JassParser::FunctionBlockContext::ENDFUNCTION() {
  return getToken(JassParser::ENDFUNCTION, 0);
}

tree::TerminalNode* JassParser::FunctionBlockContext::CONSTANT() {
  return getToken(JassParser::CONSTANT, 0);
}


size_t JassParser::FunctionBlockContext::getRuleIndex() const {
  return JassParser::RuleFunctionBlock;
}

void JassParser::FunctionBlockContext::enterRule(tree::ParseTreeListener *listener) {
  auto parserListener = dynamic_cast<JassListener *>(listener);
  if (parserListener != nullptr)
    parserListener->enterFunctionBlock(this);
}

void JassParser::FunctionBlockContext::exitRule(tree::ParseTreeListener *listener) {
  auto parserListener = dynamic_cast<JassListener *>(listener);
  if (parserListener != nullptr)
    parserListener->exitFunctionBlock(this);
}


std::any JassParser::FunctionBlockContext::accept(tree::ParseTreeVisitor *visitor) {
  if (auto parserVisitor = dynamic_cast<JassVisitor*>(visitor))
    return parserVisitor->visitFunctionBlock(this);
  else
    return visitor->visitChildren(this);
}

JassParser::FunctionBlockContext* JassParser::functionBlock() {
  FunctionBlockContext *_localctx = _tracker.createInstance<FunctionBlockContext>(_ctx, getState());
  enterRule(_localctx, 48, JassParser::RuleFunctionBlock);
  size_t _la = 0;

#if __cplusplus > 201703L
  auto onExit = finally([=, this] {
#else
  auto onExit = finally([=] {
#endif
    exitRule();
  });
  try {
    enterOuterAlt(_localctx, 1);
    setState(364);
    _errHandler->sync(this);

    _la = _input->LA(1);
    if (_la == JassParser::CONSTANT) {
      setState(363);
      match(JassParser::CONSTANT);
    }
    setState(366);
    match(JassParser::FUNCTION);
    setState(367);
    match(JassParser::ID);
    setState(368);
    match(JassParser::TAKES);
    setState(369);
    paramList();
    setState(370);
    match(JassParser::RETURNS);
    setState(371);
    type();
    setState(372);
    newlines();
    setState(373);
    statements();
    setState(374);
    match(JassParser::ENDFUNCTION);
    setState(375);
    newlines();
   
  }
  catch (RecognitionException &e) {
    _errHandler->reportError(this, e);
    _localctx->exception = std::current_exception();
    _errHandler->recover(this, _localctx->exception);
  }

  return _localctx;
}

//----------------- StatementsContext ------------------------------------------------------------------

JassParser::StatementsContext::StatementsContext(ParserRuleContext *parent, size_t invokingState)
  : ParserRuleContext(parent, invokingState) {
}

std::vector<JassParser::StatementContext *> JassParser::StatementsContext::statement() {
  return getRuleContexts<JassParser::StatementContext>();
}

JassParser::StatementContext* JassParser::StatementsContext::statement(size_t i) {
  return getRuleContext<JassParser::StatementContext>(i);
}


size_t JassParser::StatementsContext::getRuleIndex() const {
  return JassParser::RuleStatements;
}

void JassParser::StatementsContext::enterRule(tree::ParseTreeListener *listener) {
  auto parserListener = dynamic_cast<JassListener *>(listener);
  if (parserListener != nullptr)
    parserListener->enterStatements(this);
}

void JassParser::StatementsContext::exitRule(tree::ParseTreeListener *listener) {
  auto parserListener = dynamic_cast<JassListener *>(listener);
  if (parserListener != nullptr)
    parserListener->exitStatements(this);
}


std::any JassParser::StatementsContext::accept(tree::ParseTreeVisitor *visitor) {
  if (auto parserVisitor = dynamic_cast<JassVisitor*>(visitor))
    return parserVisitor->visitStatements(this);
  else
    return visitor->visitChildren(this);
}

JassParser::StatementsContext* JassParser::statements() {
  StatementsContext *_localctx = _tracker.createInstance<StatementsContext>(_ctx, getState());
  enterRule(_localctx, 50, JassParser::RuleStatements);
  size_t _la = 0;

#if __cplusplus > 201703L
  auto onExit = finally([=, this] {
#else
  auto onExit = finally([=] {
#endif
    exitRule();
  });
  try {
    enterOuterAlt(_localctx, 1);
    setState(380);
    _errHandler->sync(this);
    _la = _input->LA(1);
    while ((((_la & ~ 0x3fULL) == 0) &&
      ((1ULL << _la) & 3713234108416) != 0)) {
      setState(377);
      statement();
      setState(382);
      _errHandler->sync(this);
      _la = _input->LA(1);
    }
   
  }
  catch (RecognitionException &e) {
    _errHandler->reportError(this, e);
    _localctx->exception = std::current_exception();
    _errHandler->recover(this, _localctx->exception);
  }

  return _localctx;
}

//----------------- NewlinesContext ------------------------------------------------------------------

JassParser::NewlinesContext::NewlinesContext(ParserRuleContext *parent, size_t invokingState)
  : ParserRuleContext(parent, invokingState) {
}

JassParser::PnewlinesContext* JassParser::NewlinesContext::pnewlines() {
  return getRuleContext<JassParser::PnewlinesContext>(0);
}

tree::TerminalNode* JassParser::NewlinesContext::EOF() {
  return getToken(JassParser::EOF, 0);
}


size_t JassParser::NewlinesContext::getRuleIndex() const {
  return JassParser::RuleNewlines;
}

void JassParser::NewlinesContext::enterRule(tree::ParseTreeListener *listener) {
  auto parserListener = dynamic_cast<JassListener *>(listener);
  if (parserListener != nullptr)
    parserListener->enterNewlines(this);
}

void JassParser::NewlinesContext::exitRule(tree::ParseTreeListener *listener) {
  auto parserListener = dynamic_cast<JassListener *>(listener);
  if (parserListener != nullptr)
    parserListener->exitNewlines(this);
}


std::any JassParser::NewlinesContext::accept(tree::ParseTreeVisitor *visitor) {
  if (auto parserVisitor = dynamic_cast<JassVisitor*>(visitor))
    return parserVisitor->visitNewlines(this);
  else
    return visitor->visitChildren(this);
}

JassParser::NewlinesContext* JassParser::newlines() {
  NewlinesContext *_localctx = _tracker.createInstance<NewlinesContext>(_ctx, getState());
  enterRule(_localctx, 52, JassParser::RuleNewlines);

#if __cplusplus > 201703L
  auto onExit = finally([=, this] {
#else
  auto onExit = finally([=] {
#endif
    exitRule();
  });
  try {
    setState(385);
    _errHandler->sync(this);
    switch (_input->LA(1)) {
      case JassParser::NEWLINE: {
        enterOuterAlt(_localctx, 1);
        setState(383);
        pnewlines();
        break;
      }

      case JassParser::EOF: {
        enterOuterAlt(_localctx, 2);
        setState(384);
        match(JassParser::EOF);
        break;
      }

    default:
      throw NoViableAltException(this);
    }
   
  }
  catch (RecognitionException &e) {
    _errHandler->reportError(this, e);
    _localctx->exception = std::current_exception();
    _errHandler->recover(this, _localctx->exception);
  }

  return _localctx;
}

//----------------- Newlines_optContext ------------------------------------------------------------------

JassParser::Newlines_optContext::Newlines_optContext(ParserRuleContext *parent, size_t invokingState)
  : ParserRuleContext(parent, invokingState) {
}

JassParser::PnewlinesContext* JassParser::Newlines_optContext::pnewlines() {
  return getRuleContext<JassParser::PnewlinesContext>(0);
}

tree::TerminalNode* JassParser::Newlines_optContext::EOF() {
  return getToken(JassParser::EOF, 0);
}


size_t JassParser::Newlines_optContext::getRuleIndex() const {
  return JassParser::RuleNewlines_opt;
}

void JassParser::Newlines_optContext::enterRule(tree::ParseTreeListener *listener) {
  auto parserListener = dynamic_cast<JassListener *>(listener);
  if (parserListener != nullptr)
    parserListener->enterNewlines_opt(this);
}

void JassParser::Newlines_optContext::exitRule(tree::ParseTreeListener *listener) {
  auto parserListener = dynamic_cast<JassListener *>(listener);
  if (parserListener != nullptr)
    parserListener->exitNewlines_opt(this);
}


std::any JassParser::Newlines_optContext::accept(tree::ParseTreeVisitor *visitor) {
  if (auto parserVisitor = dynamic_cast<JassVisitor*>(visitor))
    return parserVisitor->visitNewlines_opt(this);
  else
    return visitor->visitChildren(this);
}

JassParser::Newlines_optContext* JassParser::newlines_opt() {
  Newlines_optContext *_localctx = _tracker.createInstance<Newlines_optContext>(_ctx, getState());
  enterRule(_localctx, 54, JassParser::RuleNewlines_opt);

#if __cplusplus > 201703L
  auto onExit = finally([=, this] {
#else
  auto onExit = finally([=] {
#endif
    exitRule();
  });
  try {
    setState(390);
    _errHandler->sync(this);
    switch (getInterpreter<atn::ParserATNSimulator>()->adaptivePredict(_input, 31, _ctx)) {
    case 1: {
      enterOuterAlt(_localctx, 1);
      setState(387);
      pnewlines();
      break;
    }

    case 2: {
      enterOuterAlt(_localctx, 2);
      setState(388);
      match(JassParser::EOF);
      break;
    }

    case 3: {
      enterOuterAlt(_localctx, 3);

      break;
    }

    default:
      break;
    }
   
  }
  catch (RecognitionException &e) {
    _errHandler->reportError(this, e);
    _localctx->exception = std::current_exception();
    _errHandler->recover(this, _localctx->exception);
  }

  return _localctx;
}

//----------------- PnewlinesContext ------------------------------------------------------------------

JassParser::PnewlinesContext::PnewlinesContext(ParserRuleContext *parent, size_t invokingState)
  : ParserRuleContext(parent, invokingState) {
}

tree::TerminalNode* JassParser::PnewlinesContext::NEWLINE() {
  return getToken(JassParser::NEWLINE, 0);
}

JassParser::NewlinesContext* JassParser::PnewlinesContext::newlines() {
  return getRuleContext<JassParser::NewlinesContext>(0);
}


size_t JassParser::PnewlinesContext::getRuleIndex() const {
  return JassParser::RulePnewlines;
}

void JassParser::PnewlinesContext::enterRule(tree::ParseTreeListener *listener) {
  auto parserListener = dynamic_cast<JassListener *>(listener);
  if (parserListener != nullptr)
    parserListener->enterPnewlines(this);
}

void JassParser::PnewlinesContext::exitRule(tree::ParseTreeListener *listener) {
  auto parserListener = dynamic_cast<JassListener *>(listener);
  if (parserListener != nullptr)
    parserListener->exitPnewlines(this);
}


std::any JassParser::PnewlinesContext::accept(tree::ParseTreeVisitor *visitor) {
  if (auto parserVisitor = dynamic_cast<JassVisitor*>(visitor))
    return parserVisitor->visitPnewlines(this);
  else
    return visitor->visitChildren(this);
}

JassParser::PnewlinesContext* JassParser::pnewlines() {
  PnewlinesContext *_localctx = _tracker.createInstance<PnewlinesContext>(_ctx, getState());
  enterRule(_localctx, 56, JassParser::RulePnewlines);

#if __cplusplus > 201703L
  auto onExit = finally([=, this] {
#else
  auto onExit = finally([=] {
#endif
    exitRule();
  });
  try {
    setState(395);
    _errHandler->sync(this);
    switch (getInterpreter<atn::ParserATNSimulator>()->adaptivePredict(_input, 32, _ctx)) {
    case 1: {
      enterOuterAlt(_localctx, 1);
      setState(392);
      match(JassParser::NEWLINE);
      break;
    }

    case 2: {
      enterOuterAlt(_localctx, 2);
      setState(393);
      match(JassParser::NEWLINE);
      setState(394);
      newlines();
      break;
    }

    default:
      break;
    }
   
  }
  catch (RecognitionException &e) {
    _errHandler->reportError(this, e);
    _localctx->exception = std::current_exception();
    _errHandler->recover(this, _localctx->exception);
  }

  return _localctx;
}

bool JassParser::sempred(RuleContext *context, size_t ruleIndex, size_t predicateIndex) {
  switch (ruleIndex) {
    case 6: return multDivExpressionSempred(antlrcpp::downCast<MultDivExpressionContext *>(context), predicateIndex);
    case 7: return simpleArithmeticExpressionSempred(antlrcpp::downCast<SimpleArithmeticExpressionContext *>(context), predicateIndex);
    case 8: return boolComparisonExpressionSempred(antlrcpp::downCast<BoolComparisonExpressionContext *>(context), predicateIndex);
    case 9: return boolEqualityExpressionSempred(antlrcpp::downCast<BoolEqualityExpressionContext *>(context), predicateIndex);
    case 10: return boolAndsExpressionSempred(antlrcpp::downCast<BoolAndsExpressionContext *>(context), predicateIndex);
    case 11: return boolExpressionSempred(antlrcpp::downCast<BoolExpressionContext *>(context), predicateIndex);

  default:
    break;
  }
  return true;
}

bool JassParser::multDivExpressionSempred(MultDivExpressionContext *_localctx, size_t predicateIndex) {
  switch (predicateIndex) {
    case 0: return precpred(_ctx, 3);
    case 1: return precpred(_ctx, 2);

  default:
    break;
  }
  return true;
}

bool JassParser::simpleArithmeticExpressionSempred(SimpleArithmeticExpressionContext *_localctx, size_t predicateIndex) {
  switch (predicateIndex) {
    case 2: return precpred(_ctx, 3);
    case 3: return precpred(_ctx, 2);

  default:
    break;
  }
  return true;
}

bool JassParser::boolComparisonExpressionSempred(BoolComparisonExpressionContext *_localctx, size_t predicateIndex) {
  switch (predicateIndex) {
    case 4: return precpred(_ctx, 5);
    case 5: return precpred(_ctx, 4);
    case 6: return precpred(_ctx, 3);
    case 7: return precpred(_ctx, 2);

  default:
    break;
  }
  return true;
}

bool JassParser::boolEqualityExpressionSempred(BoolEqualityExpressionContext *_localctx, size_t predicateIndex) {
  switch (predicateIndex) {
    case 8: return precpred(_ctx, 3);
    case 9: return precpred(_ctx, 2);

  default:
    break;
  }
  return true;
}

bool JassParser::boolAndsExpressionSempred(BoolAndsExpressionContext *_localctx, size_t predicateIndex) {
  switch (predicateIndex) {
    case 10: return precpred(_ctx, 2);

  default:
    break;
  }
  return true;
}

bool JassParser::boolExpressionSempred(BoolExpressionContext *_localctx, size_t predicateIndex) {
  switch (predicateIndex) {
    case 11: return precpred(_ctx, 2);

  default:
    break;
  }
  return true;
}

void JassParser::initialize() {
#if ANTLR4_USE_THREAD_LOCAL_CACHE
  jassParserInitialize();
#else
  ::antlr4::internal::call_once(jassParserOnceFlag, jassParserInitialize);
#endif
}
